diff options
| author | 2012-01-23 14:34:55 -0800 | |
|---|---|---|
| committer | 2012-01-23 14:34:55 -0800 | |
| commit | fc5851579ad316cffcacf231c5c04bda47b4517f (patch) | |
| tree | c0d74da5f64f07025ee14a24a3278d39891e4439 | |
| parent | 3909242141d6735dbae96729716ccabaa9490fd5 (diff) | |
| parent | fd1c5ed3705b885ce50b5ecad04ce699248b1d84 (diff) | |
Merge "New screen rotation animation design."
| -rw-r--r-- | core/res/res/anim/screen_rotate_180_enter.xml | 16 | ||||
| -rw-r--r-- | core/res/res/anim/screen_rotate_180_exit.xml | 14 | ||||
| -rw-r--r-- | core/res/res/anim/screen_rotate_finish_enter.xml | 36 | ||||
| -rw-r--r-- | core/res/res/anim/screen_rotate_finish_exit.xml | 41 | ||||
| -rw-r--r-- | core/res/res/anim/screen_rotate_minus_90_enter.xml | 36 | ||||
| -rw-r--r-- | core/res/res/anim/screen_rotate_minus_90_exit.xml | 37 | ||||
| -rw-r--r-- | core/res/res/anim/screen_rotate_plus_90_enter.xml | 36 | ||||
| -rw-r--r-- | core/res/res/anim/screen_rotate_plus_90_exit.xml | 37 | ||||
| -rw-r--r-- | core/res/res/anim/screen_rotate_start_enter.xml | 29 | ||||
| -rw-r--r-- | core/res/res/anim/screen_rotate_start_exit.xml | 29 | ||||
| -rw-r--r-- | services/java/com/android/server/wm/ScreenRotationAnimation.java | 416 | ||||
| -rw-r--r-- | services/java/com/android/server/wm/WindowManagerService.java | 93 |
12 files changed, 674 insertions, 146 deletions
diff --git a/core/res/res/anim/screen_rotate_180_enter.xml b/core/res/res/anim/screen_rotate_180_enter.xml index 95cc562fb32d..470416babcac 100644 --- a/core/res/res/anim/screen_rotate_180_enter.xml +++ b/core/res/res/anim/screen_rotate_180_enter.xml @@ -19,16 +19,10 @@ <set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="false"> - <scale android:fromXScale="1.0" android:toXScale="1.0" - android:fromYScale=".9" android:toYScale="1.0" - android:pivotX="50%p" android:pivotY="50%p" - android:fillEnabled="true" android:fillBefore="true" + <rotate android:fromDegrees="180" android:toDegrees="0" + android:pivotX="50%" android:pivotY="50%" android:interpolator="@interpolator/decelerate_quint" - android:startOffset="160" - android:duration="300" /> - <alpha android:fromAlpha="0" android:toAlpha="1.0" - android:fillEnabled="true" android:fillBefore="true" - android:interpolator="@interpolator/decelerate_quint" - android:startOffset="160" - android:duration="300"/> + android:fillEnabled="true" + android:fillBefore="true" android:fillAfter="true" + android:duration="@android:integer/config_mediumAnimTime" /> </set>
\ No newline at end of file diff --git a/core/res/res/anim/screen_rotate_180_exit.xml b/core/res/res/anim/screen_rotate_180_exit.xml index d3dd4c05749c..58a1868bd398 100644 --- a/core/res/res/anim/screen_rotate_180_exit.xml +++ b/core/res/res/anim/screen_rotate_180_exit.xml @@ -19,12 +19,10 @@ <set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="false"> - <scale android:fromXScale="1.0" android:toXScale="1.0" - android:fromYScale="1.0" android:toYScale="0.0" - android:pivotX="50%p" android:pivotY="50%p" - android:interpolator="@interpolator/accelerate_cubic" - android:duration="160" /> - <alpha android:fromAlpha="1.0" android:toAlpha="0" - android:interpolator="@interpolator/decelerate_cubic" - android:duration="160"/> + <rotate android:fromDegrees="0" android:toDegrees="-180" + android:pivotX="50%" android:pivotY="50%" + android:interpolator="@interpolator/decelerate_quint" + android:fillEnabled="true" + android:fillBefore="true" android:fillAfter="true" + android:duration="@android:integer/config_mediumAnimTime" /> </set>
\ No newline at end of file diff --git a/core/res/res/anim/screen_rotate_finish_enter.xml b/core/res/res/anim/screen_rotate_finish_enter.xml new file mode 100644 index 000000000000..849aa66132a2 --- /dev/null +++ b/core/res/res/anim/screen_rotate_finish_enter.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 2012, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> + +<set xmlns:android="http://schemas.android.com/apk/res/android" + android:shareInterpolator="false"> + <scale android:fromXScale="1.0" android:toXScale="1.25" + android:fromYScale="1.0" android:toYScale="1.25" + android:pivotX="50%" android:pivotY="50%" + android:interpolator="@interpolator/decelerate_quint" + android:fillEnabled="true" + android:fillBefore="true" android:fillAfter="true" + android:duration="@android:integer/config_mediumAnimTime"/> + <scale android:fromXScale="100%p" android:toXScale="100%" + android:fromYScale="100%p" android:toYScale="100%" + android:pivotX="50%" android:pivotY="50%" + android:interpolator="@interpolator/decelerate_quint" + android:fillEnabled="true" + android:fillBefore="true" android:fillAfter="true" + android:duration="@android:integer/config_mediumAnimTime" /> +</set> diff --git a/core/res/res/anim/screen_rotate_finish_exit.xml b/core/res/res/anim/screen_rotate_finish_exit.xml new file mode 100644 index 000000000000..7f70dbcbaa50 --- /dev/null +++ b/core/res/res/anim/screen_rotate_finish_exit.xml @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 2012, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> + +<set xmlns:android="http://schemas.android.com/apk/res/android" + android:shareInterpolator="false"> + <scale android:fromXScale="1.0" android:toXScale="1.25" + android:fromYScale="1.0" android:toYScale="1.25" + android:pivotX="50%" android:pivotY="50%" + android:interpolator="@interpolator/decelerate_quint" + android:fillEnabled="true" + android:fillBefore="false" android:fillAfter="true" + android:duration="@android:integer/config_mediumAnimTime"/> + <!-- + <scale android:fromXScale="100%" android:toXScale="100%p" + android:fromYScale="100%" android:toYScale="100%p" + android:pivotX="50%" android:pivotY="50%" + android:interpolator="@interpolator/decelerate_quint" + android:duration="@android:integer/config_mediumAnimTime" /> + --> + <alpha android:fromAlpha="1.0" android:toAlpha="0" + android:interpolator="@interpolator/decelerate_quint" + android:fillEnabled="true" + android:fillBefore="true" android:fillAfter="true" + android:duration="@android:integer/config_mediumAnimTime" /> +</set> diff --git a/core/res/res/anim/screen_rotate_minus_90_enter.xml b/core/res/res/anim/screen_rotate_minus_90_enter.xml index 61aa72a3b307..d2aebc9d93d1 100644 --- a/core/res/res/anim/screen_rotate_minus_90_enter.xml +++ b/core/res/res/anim/screen_rotate_minus_90_enter.xml @@ -19,8 +19,44 @@ <set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="false"> + <!-- + <scale android:fromXScale="1.0" android:toXScale="0.565" + android:fromYScale="1.0" android:toYScale="0.565" + android:pivotX="50%" android:pivotY="50%" + android:interpolator="@interpolator/decelerate_quint" + android:fillEnabled="true" + android:fillBefore="false" android:fillAfter="true" + android:duration="@android:integer/config_mediumAnimTime"/> + <scale android:fromXScale="1.0" android:toXScale="1.777777777" + android:fromYScale="1.0" android:toYScale="1.777777777" + android:pivotX="50%" android:pivotY="50%" + android:interpolator="@interpolator/decelerate_quint" + android:fillEnabled="true" + android:fillBefore="false" android:fillAfter="true" + android:startOffset="@android:integer/config_longAnimTime" + android:duration="@android:integer/config_mediumAnimTime"/> + <scale android:fromXScale="100%p" android:toXScale="100%" + android:fromYScale="100%p" android:toYScale="100%" + android:pivotX="50%" android:pivotY="50%" + android:interpolator="@interpolator/decelerate_quint" + android:fillEnabled="true" + android:fillBefore="true" android:fillAfter="true" + android:startOffset="@android:integer/config_longAnimTime" + android:duration="@android:integer/config_mediumAnimTime" /> + --> + <!-- + <scale android:fromXScale="100%p" android:toXScale="100%" + android:fromYScale="100%p" android:toYScale="100%" + android:pivotX="50%" android:pivotY="50%" + android:interpolator="@interpolator/decelerate_quint" + android:fillEnabled="true" + android:fillBefore="true" android:fillAfter="true" + android:duration="@android:integer/config_mediumAnimTime" /> + --> <rotate android:fromDegrees="-90" android:toDegrees="0" android:pivotX="50%" android:pivotY="50%" android:interpolator="@interpolator/decelerate_quint" + android:fillEnabled="true" + android:fillBefore="true" android:fillAfter="true" android:duration="@android:integer/config_mediumAnimTime" /> </set> diff --git a/core/res/res/anim/screen_rotate_minus_90_exit.xml b/core/res/res/anim/screen_rotate_minus_90_exit.xml index 65294f662438..c7c38cd8c6ca 100644 --- a/core/res/res/anim/screen_rotate_minus_90_exit.xml +++ b/core/res/res/anim/screen_rotate_minus_90_exit.xml @@ -19,16 +19,51 @@ <set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="false"> + <!-- + <scale android:fromXScale="1.0" android:toXScale="0.565" + android:fromYScale="1.0" android:toYScale="0.565" + android:pivotX="50%" android:pivotY="50%" + android:interpolator="@interpolator/decelerate_quint" + android:fillEnabled="true" + android:fillBefore="false" android:fillAfter="true" + android:duration="@android:integer/config_mediumAnimTime"/> + <scale android:fromXScale="1.0" android:toXScale="1.777777777" + android:fromYScale="1.0" android:toYScale="1.777777777" + android:pivotX="50%" android:pivotY="50%" + android:interpolator="@interpolator/decelerate_quint" + android:fillEnabled="true" + android:fillBefore="false" android:fillAfter="true" + android:startOffset="@android:integer/config_longAnimTime" + android:duration="@android:integer/config_mediumAnimTime"/> <scale android:fromXScale="100%" android:toXScale="100%p" android:fromYScale="100%" android:toYScale="100%p" android:pivotX="50%" android:pivotY="50%" android:interpolator="@interpolator/decelerate_quint" + android:startOffset="@android:integer/config_longAnimTime" android:duration="@android:integer/config_mediumAnimTime" /> - <rotate android:fromDegrees="0" android:toDegrees="90" + <alpha android:fromAlpha="1.0" android:toAlpha="0" + android:interpolator="@interpolator/decelerate_quint" + android:fillEnabled="true" + android:fillBefore="false" android:fillAfter="true" + android:startOffset="@android:integer/config_longAnimTime" + android:duration="@android:integer/config_mediumAnimTime" /> + --> + <!-- + <scale android:fromXScale="100%" android:toXScale="100%p" + android:fromYScale="100%" android:toYScale="100%p" android:pivotX="50%" android:pivotY="50%" android:interpolator="@interpolator/decelerate_quint" android:duration="@android:integer/config_mediumAnimTime" /> <alpha android:fromAlpha="1.0" android:toAlpha="0" android:interpolator="@interpolator/decelerate_quint" + android:fillEnabled="true" + android:fillBefore="false" android:fillAfter="true" + android:duration="@android:integer/config_mediumAnimTime" /> + --> + <rotate android:fromDegrees="0" android:toDegrees="90" + android:pivotX="50%" android:pivotY="50%" + android:interpolator="@interpolator/decelerate_quint" + android:fillEnabled="true" + android:fillBefore="true" android:fillAfter="true" android:duration="@android:integer/config_mediumAnimTime" /> </set> diff --git a/core/res/res/anim/screen_rotate_plus_90_enter.xml b/core/res/res/anim/screen_rotate_plus_90_enter.xml index 53b0ccd43f05..63d7043ca666 100644 --- a/core/res/res/anim/screen_rotate_plus_90_enter.xml +++ b/core/res/res/anim/screen_rotate_plus_90_enter.xml @@ -19,8 +19,44 @@ <set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="false"> + <!-- + <scale android:fromXScale="1.0" android:toXScale="0.565" + android:fromYScale="1.0" android:toYScale="0.565" + android:pivotX="50%" android:pivotY="50%" + android:interpolator="@interpolator/decelerate_quint" + android:fillEnabled="true" + android:fillBefore="false" android:fillAfter="true" + android:duration="@android:integer/config_mediumAnimTime"/> + <scale android:fromXScale="1.0" android:toXScale="1.777777777" + android:fromYScale="1.0" android:toYScale="1.777777777" + android:pivotX="50%" android:pivotY="50%" + android:interpolator="@interpolator/decelerate_quint" + android:fillEnabled="true" + android:fillBefore="false" android:fillAfter="true" + android:startOffset="75" + android:duration="@android:integer/config_mediumAnimTime"/> + <scale android:fromXScale="100%p" android:toXScale="100%" + android:fromYScale="100%p" android:toYScale="100%" + android:pivotX="50%" android:pivotY="50%" + android:interpolator="@interpolator/decelerate_quint" + android:fillEnabled="true" + android:fillBefore="true" android:fillAfter="true" + android:startOffset="75" + android:duration="@android:integer/config_mediumAnimTime" /> + --> + <!-- + <scale android:fromXScale="100%p" android:toXScale="100%" + android:fromYScale="100%p" android:toYScale="100%" + android:pivotX="50%" android:pivotY="50%" + android:interpolator="@interpolator/decelerate_quint" + android:fillEnabled="true" + android:fillBefore="true" android:fillAfter="true" + android:duration="@android:integer/config_mediumAnimTime" /> + --> <rotate android:fromDegrees="90" android:toDegrees="0" android:pivotX="50%" android:pivotY="50%" android:interpolator="@interpolator/decelerate_quint" + android:fillEnabled="true" + android:fillBefore="true" android:fillAfter="true" android:duration="@android:integer/config_mediumAnimTime" /> </set> diff --git a/core/res/res/anim/screen_rotate_plus_90_exit.xml b/core/res/res/anim/screen_rotate_plus_90_exit.xml index 63c0b09274a7..ea48c814c225 100644 --- a/core/res/res/anim/screen_rotate_plus_90_exit.xml +++ b/core/res/res/anim/screen_rotate_plus_90_exit.xml @@ -19,16 +19,51 @@ <set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="false"> + <!-- + <scale android:fromXScale="1.0" android:toXScale="0.565" + android:fromYScale="1.0" android:toYScale="0.565" + android:pivotX="50%" android:pivotY="50%" + android:interpolator="@interpolator/decelerate_quint" + android:fillEnabled="true" + android:fillBefore="false" android:fillAfter="true" + android:duration="@android:integer/config_mediumAnimTime"/> + <scale android:fromXScale="1.0" android:toXScale="1.777777777" + android:fromYScale="1.0" android:toYScale="1.777777777" + android:pivotX="50%" android:pivotY="50%" + android:interpolator="@interpolator/decelerate_quint" + android:fillEnabled="true" + android:fillBefore="false" android:fillAfter="true" + android:startOffset="75" + android:duration="@android:integer/config_mediumAnimTime"/> <scale android:fromXScale="100%" android:toXScale="100%p" android:fromYScale="100%" android:toYScale="100%p" android:pivotX="50%" android:pivotY="50%" android:interpolator="@interpolator/decelerate_quint" + android:startOffset="75" android:duration="@android:integer/config_mediumAnimTime" /> - <rotate android:fromDegrees="0" android:toDegrees="-90" + <alpha android:fromAlpha="1.0" android:toAlpha="0" + android:interpolator="@interpolator/decelerate_quint" + android:fillEnabled="true" + android:fillBefore="false" android:fillAfter="true" + android:startOffset="75" + android:duration="@android:integer/config_mediumAnimTime" /> + --> + <!-- + <scale android:fromXScale="100%" android:toXScale="100%p" + android:fromYScale="100%" android:toYScale="100%p" android:pivotX="50%" android:pivotY="50%" android:interpolator="@interpolator/decelerate_quint" android:duration="@android:integer/config_mediumAnimTime" /> <alpha android:fromAlpha="1.0" android:toAlpha="0" android:interpolator="@interpolator/decelerate_quint" + android:fillEnabled="true" + android:fillBefore="false" android:fillAfter="true" + android:duration="@android:integer/config_mediumAnimTime" /> + --> + <rotate android:fromDegrees="0" android:toDegrees="-90" + android:pivotX="50%" android:pivotY="50%" + android:interpolator="@interpolator/decelerate_quint" + android:fillEnabled="true" + android:fillBefore="true" android:fillAfter="true" android:duration="@android:integer/config_mediumAnimTime" /> </set> diff --git a/core/res/res/anim/screen_rotate_start_enter.xml b/core/res/res/anim/screen_rotate_start_enter.xml new file mode 100644 index 000000000000..e3f48e4d1154 --- /dev/null +++ b/core/res/res/anim/screen_rotate_start_enter.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 2012, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> + +<set xmlns:android="http://schemas.android.com/apk/res/android" + android:shareInterpolator="false"> + <scale android:fromXScale="1.0" android:toXScale="0.8" + android:fromYScale="1.0" android:toYScale="0.8" + android:pivotX="50%" android:pivotY="50%" + android:interpolator="@interpolator/decelerate_quint" + android:fillEnabled="true" + android:fillBefore="true" android:fillAfter="true" + android:duration="@android:integer/config_mediumAnimTime"/> +</set> diff --git a/core/res/res/anim/screen_rotate_start_exit.xml b/core/res/res/anim/screen_rotate_start_exit.xml new file mode 100644 index 000000000000..e3f48e4d1154 --- /dev/null +++ b/core/res/res/anim/screen_rotate_start_exit.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 2012, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> + +<set xmlns:android="http://schemas.android.com/apk/res/android" + android:shareInterpolator="false"> + <scale android:fromXScale="1.0" android:toXScale="0.8" + android:fromYScale="1.0" android:toYScale="0.8" + android:pivotX="50%" android:pivotY="50%" + android:interpolator="@interpolator/decelerate_quint" + android:fillEnabled="true" + android:fillBefore="true" android:fillAfter="true" + android:duration="@android:integer/config_mediumAnimTime"/> +</set> diff --git a/services/java/com/android/server/wm/ScreenRotationAnimation.java b/services/java/com/android/server/wm/ScreenRotationAnimation.java index 8fc9a70faad9..55fb03831b6c 100644 --- a/services/java/com/android/server/wm/ScreenRotationAnimation.java +++ b/services/java/com/android/server/wm/ScreenRotationAnimation.java @@ -17,13 +17,8 @@ package com.android.server.wm; import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.Canvas; import android.graphics.Matrix; -import android.graphics.Paint; import android.graphics.PixelFormat; -import android.graphics.PorterDuff; -import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.util.Slog; import android.view.Surface; @@ -34,7 +29,8 @@ import android.view.animation.Transformation; class ScreenRotationAnimation { static final String TAG = "ScreenRotationAnimation"; - static final boolean DEBUG = false; + static final boolean DEBUG_STATE = false; + static final boolean DEBUG_TRANSFORMS = false; static final int FREEZE_LAYER = WindowManagerService.TYPE_LAYER_MULTIPLIER * 200; @@ -49,11 +45,51 @@ class ScreenRotationAnimation { int mOriginalWidth, mOriginalHeight; int mCurRotation; - Animation mExitAnimation; + // For all animations, "exit" is for the UI elements that are going + // away (that is the snapshot of the old screen), and "enter" is for + // the new UI elements that are appearing (that is the active windows + // in their final orientation). + + // The starting animation for the exiting and entering elements. This + // animation applies a transformation while the rotation is in progress. + // It is started immediately, before the new entering UI is ready. + Animation mStartExitAnimation; + final Transformation mStartExitTransformation = new Transformation(); + Animation mStartEnterAnimation; + final Transformation mStartEnterTransformation = new Transformation(); + + // The finishing animation for the exiting and entering elements. This + // animation needs to undo the transformation of the starting animation. + // It starts running once the new rotation UI elements are ready to be + // displayed. + Animation mFinishExitAnimation; + final Transformation mFinishExitTransformation = new Transformation(); + Animation mFinishEnterAnimation; + final Transformation mFinishEnterTransformation = new Transformation(); + + // The current active animation to move from the old to the new rotated + // state. Which animation is run here will depend on the old and new + // rotations. + Animation mRotateExitAnimation; + final Transformation mRotateExitTransformation = new Transformation(); + Animation mRotateEnterAnimation; + final Transformation mRotateEnterTransformation = new Transformation(); + + // A previously running rotate animation. This will be used if we need + // to switch to a new rotation before finishing the previous one. + Animation mLastRotateExitAnimation; + final Transformation mLastRotateExitTransformation = new Transformation(); + Animation mLastRotateEnterAnimation; + final Transformation mLastRotateEnterTransformation = new Transformation(); + + // Complete transformations being applied. final Transformation mExitTransformation = new Transformation(); - Animation mEnterAnimation; final Transformation mEnterTransformation = new Transformation(); + boolean mStarted; + boolean mAnimRunning; + boolean mFinishAnimReady; + long mFinishAnimStartTime; final Matrix mSnapshotInitialMatrix = new Matrix(); final Matrix mSnapshotFinalMatrix = new Matrix(); @@ -133,7 +169,7 @@ class ScreenRotationAnimation { mTmpFloats[Matrix.MSCALE_X], mTmpFloats[Matrix.MSKEW_Y], mTmpFloats[Matrix.MSKEW_X], mTmpFloats[Matrix.MSCALE_Y]); mSurface.setAlpha(alpha); - if (DEBUG) { + if (DEBUG_TRANSFORMS) { float[] srcPnts = new float[] { 0, 0, mWidth, mHeight }; float[] dstPnts = new float[4]; matrix.mapPoints(dstPnts, srcPnts); @@ -167,7 +203,7 @@ class ScreenRotationAnimation { } // Must be called while in a transaction. - public void setRotation(int rotation) { + private void setRotation(int rotation) { mCurRotation = rotation; // Compute the transformation matrix that must be applied @@ -176,46 +212,78 @@ class ScreenRotationAnimation { int delta = deltaRotation(rotation, mSnapshotRotation); createRotationMatrix(delta, mWidth, mHeight, mSnapshotInitialMatrix); - if (DEBUG) Slog.v(TAG, "**** ROTATION: " + delta); + if (DEBUG_STATE) Slog.v(TAG, "**** ROTATION: " + delta); setSnapshotTransform(mSnapshotInitialMatrix, 1.0f); } + // Must be called while in a transaction. + public boolean setRotation(int rotation, SurfaceSession session, + long maxAnimationDuration, float animationScale, int finalWidth, int finalHeight) { + setRotation(rotation); + return startAnimation(session, maxAnimationDuration, animationScale, + finalWidth, finalHeight, false); + } + /** * Returns true if animating. */ - public boolean dismiss(SurfaceSession session, long maxAnimationDuration, - float animationScale, int finalWidth, int finalHeight) { + private boolean startAnimation(SurfaceSession session, long maxAnimationDuration, + float animationScale, int finalWidth, int finalHeight, boolean dismissing) { if (mSurface == null) { // Can't do animation. return false; } + if (mStarted) { + return true; + } + + mStarted = true; + + boolean firstStart = false; // Figure out how the screen has moved from the original rotation. int delta = deltaRotation(mCurRotation, mOriginalRotation); + if (mFinishExitAnimation == null && (!dismissing || delta != Surface.ROTATION_0)) { + if (DEBUG_STATE) Slog.v(TAG, "Creating start and finish animations"); + firstStart = true; + mStartExitAnimation = AnimationUtils.loadAnimation(mContext, + com.android.internal.R.anim.screen_rotate_start_exit); + mStartEnterAnimation = AnimationUtils.loadAnimation(mContext, + com.android.internal.R.anim.screen_rotate_start_enter); + mFinishExitAnimation = AnimationUtils.loadAnimation(mContext, + com.android.internal.R.anim.screen_rotate_finish_exit); + mFinishEnterAnimation = AnimationUtils.loadAnimation(mContext, + com.android.internal.R.anim.screen_rotate_finish_enter); + } + + if (DEBUG_STATE) Slog.v(TAG, "Rotation delta: " + delta + " finalWidth=" + + finalWidth + " finalHeight=" + finalHeight + + " origWidth=" + mOriginalWidth + " origHeight=" + mOriginalHeight); + switch (delta) { case Surface.ROTATION_0: - mExitAnimation = AnimationUtils.loadAnimation(mContext, + mRotateExitAnimation = AnimationUtils.loadAnimation(mContext, com.android.internal.R.anim.screen_rotate_0_exit); - mEnterAnimation = AnimationUtils.loadAnimation(mContext, + mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext, com.android.internal.R.anim.screen_rotate_0_enter); break; case Surface.ROTATION_90: - mExitAnimation = AnimationUtils.loadAnimation(mContext, + mRotateExitAnimation = AnimationUtils.loadAnimation(mContext, com.android.internal.R.anim.screen_rotate_plus_90_exit); - mEnterAnimation = AnimationUtils.loadAnimation(mContext, + mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext, com.android.internal.R.anim.screen_rotate_plus_90_enter); break; case Surface.ROTATION_180: - mExitAnimation = AnimationUtils.loadAnimation(mContext, + mRotateExitAnimation = AnimationUtils.loadAnimation(mContext, com.android.internal.R.anim.screen_rotate_180_exit); - mEnterAnimation = AnimationUtils.loadAnimation(mContext, + mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext, com.android.internal.R.anim.screen_rotate_180_enter); break; case Surface.ROTATION_270: - mExitAnimation = AnimationUtils.loadAnimation(mContext, + mRotateExitAnimation = AnimationUtils.loadAnimation(mContext, com.android.internal.R.anim.screen_rotate_minus_90_exit); - mEnterAnimation = AnimationUtils.loadAnimation(mContext, + mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext, com.android.internal.R.anim.screen_rotate_minus_90_enter); break; } @@ -224,35 +292,85 @@ class ScreenRotationAnimation { // means to allow supplying the last and next size. In this definition // "%p" is the original (let's call it "previous") size, and "%" is the // screen's current/new size. - mEnterAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight); - mExitAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight); - mStarted = false; + if (firstStart) { + if (DEBUG_STATE) Slog.v(TAG, "Initializing start and finish animations"); + mStartEnterAnimation.initialize(finalWidth, finalHeight, + mOriginalWidth, mOriginalHeight); + mStartExitAnimation.initialize(finalWidth, finalHeight, + mOriginalWidth, mOriginalHeight); + mFinishEnterAnimation.initialize(finalWidth, finalHeight, + mOriginalWidth, mOriginalHeight); + mFinishExitAnimation.initialize(finalWidth, finalHeight, + mOriginalWidth, mOriginalHeight); + } + mRotateEnterAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight); + mRotateExitAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight); + mAnimRunning = false; + mFinishAnimReady = false; + mFinishAnimStartTime = -1; + + if (firstStart) { + mStartExitAnimation.restrictDuration(maxAnimationDuration); + mStartExitAnimation.scaleCurrentDuration(animationScale); + mStartEnterAnimation.restrictDuration(maxAnimationDuration); + mStartEnterAnimation.scaleCurrentDuration(animationScale); + mFinishExitAnimation.restrictDuration(maxAnimationDuration); + mFinishExitAnimation.scaleCurrentDuration(animationScale); + mFinishEnterAnimation.restrictDuration(maxAnimationDuration); + mFinishEnterAnimation.scaleCurrentDuration(animationScale); + } + mRotateExitAnimation.restrictDuration(maxAnimationDuration); + mRotateExitAnimation.scaleCurrentDuration(animationScale); + mRotateEnterAnimation.restrictDuration(maxAnimationDuration); + mRotateEnterAnimation.scaleCurrentDuration(animationScale); + + if (mBlackFrame == null) { + if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i( + WindowManagerService.TAG, + ">>> OPEN TRANSACTION ScreenRotationAnimation.startAnimation"); + Surface.openTransaction(); - mExitAnimation.restrictDuration(maxAnimationDuration); - mExitAnimation.scaleCurrentDuration(animationScale); - mEnterAnimation.restrictDuration(maxAnimationDuration); - mEnterAnimation.scaleCurrentDuration(animationScale); + try { + Rect outer = new Rect(-finalWidth*1, -finalHeight*1, finalWidth*2, finalHeight*2); + Rect inner = new Rect(0, 0, finalWidth, finalHeight); + mBlackFrame = new BlackFrame(session, outer, inner, FREEZE_LAYER); + } catch (Surface.OutOfResourcesException e) { + Slog.w(TAG, "Unable to allocate black surface", e); + } finally { + Surface.closeTransaction(); + if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i( + WindowManagerService.TAG, + "<<< CLOSE TRANSACTION ScreenRotationAnimation.startAnimation"); + } + } - if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i(WindowManagerService.TAG, - ">>> OPEN TRANSACTION ScreenRotationAnimation.dismiss"); - Surface.openTransaction(); + return true; + } - try { - Rect outer = new Rect(-finalWidth, -finalHeight, finalWidth * 2, finalHeight * 2); - Rect inner = new Rect(0, 0, finalWidth, finalHeight); - mBlackFrame = new BlackFrame(session, outer, inner, FREEZE_LAYER); - } catch (Surface.OutOfResourcesException e) { - Slog.w(TAG, "Unable to allocate black surface", e); - } finally { - Surface.closeTransaction(); - if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i(WindowManagerService.TAG, - "<<< CLOSE TRANSACTION ScreenRotationAnimation.dismiss"); + /** + * Returns true if animating. + */ + public boolean dismiss(SurfaceSession session, long maxAnimationDuration, + float animationScale, int finalWidth, int finalHeight) { + if (DEBUG_STATE) Slog.v(TAG, "Dismiss!"); + if (mSurface == null) { + // Can't do animation. + return false; } - + if (!mStarted) { + startAnimation(session, maxAnimationDuration, animationScale, finalWidth, finalHeight, + true); + } + if (!mStarted) { + return false; + } + if (DEBUG_STATE) Slog.v(TAG, "Setting mFinishAnimReady = true"); + mFinishAnimReady = true; return true; } public void kill() { + if (DEBUG_STATE) Slog.v(TAG, "Kill!"); if (mSurface != null) { if (WindowManagerService.SHOW_TRANSACTIONS || WindowManagerService.SHOW_SURFACE_ALLOC) Slog.i(WindowManagerService.TAG, @@ -262,74 +380,198 @@ class ScreenRotationAnimation { } if (mBlackFrame != null) { mBlackFrame.kill(); + mBlackFrame = null; + } + if (mStartExitAnimation != null) { + mStartExitAnimation.cancel(); + mStartExitAnimation = null; + } + if (mStartEnterAnimation != null) { + mStartEnterAnimation.cancel(); + mStartEnterAnimation = null; } - if (mExitAnimation != null) { - mExitAnimation.cancel(); - mExitAnimation = null; + if (mFinishExitAnimation != null) { + mFinishExitAnimation.cancel(); + mFinishExitAnimation = null; } - if (mEnterAnimation != null) { - mEnterAnimation.cancel(); - mEnterAnimation = null; + if (mStartEnterAnimation != null) { + mStartEnterAnimation.cancel(); + mStartEnterAnimation = null; + } + if (mRotateExitAnimation != null) { + mRotateExitAnimation.cancel(); + mRotateExitAnimation = null; + } + if (mRotateEnterAnimation != null) { + mRotateEnterAnimation.cancel(); + mRotateEnterAnimation = null; } } public boolean isAnimating() { - return mEnterAnimation != null || mExitAnimation != null; + return mStartEnterAnimation != null || mStartExitAnimation != null + && mFinishEnterAnimation != null || mFinishExitAnimation != null + && mRotateEnterAnimation != null || mRotateExitAnimation != null; } public boolean stepAnimation(long now) { - if (mEnterAnimation == null && mExitAnimation == null) { + if (!isAnimating()) { + if (DEBUG_STATE) Slog.v(TAG, "Step: no animations running"); return false; } - if (!mStarted) { - if (mEnterAnimation != null) { - mEnterAnimation.setStartTime(now); + if (!mAnimRunning) { + if (DEBUG_STATE) Slog.v(TAG, "Step: starting start, finish, rotate"); + if (mStartEnterAnimation != null) { + mStartEnterAnimation.setStartTime(now); } - if (mExitAnimation != null) { - mExitAnimation.setStartTime(now); + if (mStartExitAnimation != null) { + mStartExitAnimation.setStartTime(now); } - mStarted = true; - } - - mExitTransformation.clear(); - boolean moreExit = false; - if (mExitAnimation != null) { - moreExit = mExitAnimation.getTransformation(now, mExitTransformation); - if (DEBUG) Slog.v(TAG, "Stepped exit: " + mExitTransformation); - if (!moreExit) { - if (DEBUG) Slog.v(TAG, "Exit animation done!"); - mExitAnimation.cancel(); - mExitAnimation = null; - mExitTransformation.clear(); - if (mSurface != null) { - mSurface.hide(); - } + if (mFinishEnterAnimation != null) { + mFinishEnterAnimation.setStartTime(0); + } + if (mFinishExitAnimation != null) { + mFinishExitAnimation.setStartTime(0); + } + if (mRotateEnterAnimation != null) { + mRotateEnterAnimation.setStartTime(now); } + if (mRotateExitAnimation != null) { + mRotateExitAnimation.setStartTime(now); + } + mAnimRunning = true; } - mEnterTransformation.clear(); - boolean moreEnter = false; - if (mEnterAnimation != null) { - moreEnter = mEnterAnimation.getTransformation(now, mEnterTransformation); - if (!moreEnter) { - mEnterAnimation.cancel(); - mEnterAnimation = null; - mEnterTransformation.clear(); - if (mBlackFrame != null) { - mBlackFrame.hide(); - } - } else { - if (mBlackFrame != null) { - mBlackFrame.setMatrix(mEnterTransformation.getMatrix()); - } + if (mFinishAnimReady && mFinishAnimStartTime < 0) { + if (DEBUG_STATE) Slog.v(TAG, "Step: finish anim now ready"); + mFinishAnimStartTime = now; + } + + // If the start animation is no longer running, we want to keep its + // transformation intact until the finish animation also completes. + + boolean moreStartExit = false; + if (mStartExitAnimation != null) { + mStartExitTransformation.clear(); + moreStartExit = mStartExitAnimation.getTransformation(now, mStartExitTransformation); + if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped start exit: " + mStartExitTransformation); + if (!moreStartExit) { + if (DEBUG_STATE) Slog.v(TAG, "Start exit animation done!"); + mStartExitAnimation.cancel(); + mStartExitAnimation = null; + } + } + + boolean moreStartEnter = false; + if (mStartEnterAnimation != null) { + mStartEnterTransformation.clear(); + moreStartEnter = mStartEnterAnimation.getTransformation(now, mStartEnterTransformation); + if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped start enter: " + mStartEnterTransformation); + if (!moreStartEnter) { + if (DEBUG_STATE) Slog.v(TAG, "Start enter animation done!"); + mStartEnterAnimation.cancel(); + mStartEnterAnimation = null; + } + } + + long finishNow = mFinishAnimReady ? (now - mFinishAnimStartTime) : 0; + if (DEBUG_STATE) Slog.v(TAG, "Step: finishNow=" + finishNow); + + mFinishExitTransformation.clear(); + boolean moreFinishExit = false; + if (mFinishExitAnimation != null) { + moreFinishExit = mFinishExitAnimation.getTransformation(finishNow, mFinishExitTransformation); + if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped finish exit: " + mFinishExitTransformation); + if (!moreStartExit && !moreFinishExit) { + if (DEBUG_STATE) Slog.v(TAG, "Finish exit animation done, clearing start/finish anims!"); + mStartExitTransformation.clear(); + mFinishExitAnimation.cancel(); + mFinishExitAnimation = null; + mFinishExitTransformation.clear(); + } + } + + mFinishEnterTransformation.clear(); + boolean moreFinishEnter = false; + if (mFinishEnterAnimation != null) { + moreFinishEnter = mFinishEnterAnimation.getTransformation(finishNow, mFinishEnterTransformation); + if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped finish enter: " + mFinishEnterTransformation); + if (!moreStartEnter && !moreFinishEnter) { + if (DEBUG_STATE) Slog.v(TAG, "Finish enter animation done, clearing start/finish anims!"); + mStartEnterTransformation.clear(); + mFinishEnterAnimation.cancel(); + mFinishEnterAnimation = null; + mFinishEnterTransformation.clear(); + } + } + + mRotateExitTransformation.clear(); + boolean moreRotateExit = false; + if (mRotateExitAnimation != null) { + moreRotateExit = mRotateExitAnimation.getTransformation(now, mRotateExitTransformation); + if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped rotate exit: " + mRotateExitTransformation); + } + + if (!moreFinishExit && !moreRotateExit) { + if (DEBUG_STATE) Slog.v(TAG, "Rotate exit animation done!"); + mRotateExitAnimation.cancel(); + mRotateExitAnimation = null; + mRotateExitTransformation.clear(); + } + + mRotateEnterTransformation.clear(); + boolean moreRotateEnter = false; + if (mRotateEnterAnimation != null) { + moreRotateEnter = mRotateEnterAnimation.getTransformation(now, mRotateEnterTransformation); + if (DEBUG_TRANSFORMS) Slog.v(TAG, "Stepped rotate enter: " + mRotateEnterTransformation); + } + + if (!moreFinishEnter && !moreRotateEnter) { + if (DEBUG_STATE) Slog.v(TAG, "Rotate enter animation done!"); + mRotateEnterAnimation.cancel(); + mRotateEnterAnimation = null; + mRotateEnterTransformation.clear(); + } + + mExitTransformation.set(mRotateExitTransformation); + mExitTransformation.compose(mStartExitTransformation); + mExitTransformation.compose(mFinishExitTransformation); + + mEnterTransformation.set(mRotateEnterTransformation); + mEnterTransformation.compose(mStartEnterTransformation); + mEnterTransformation.compose(mFinishEnterTransformation); + + if (DEBUG_TRANSFORMS) Slog.v(TAG, "Final exit: " + mExitTransformation); + if (DEBUG_TRANSFORMS) Slog.v(TAG, "Final enter: " + mEnterTransformation); + + if (!moreStartExit && !moreFinishExit && !moreRotateExit) { + if (mSurface != null) { + if (DEBUG_STATE) Slog.v(TAG, "Exit animations done, hiding screenshot surface"); + mSurface.hide(); + } + } + + if (!moreStartEnter && !moreFinishEnter && !moreRotateEnter) { + if (mBlackFrame != null) { + if (DEBUG_STATE) Slog.v(TAG, "Enter animations done, hiding black frame"); + mBlackFrame.hide(); + } + } else { + if (mBlackFrame != null) { + mBlackFrame.setMatrix(mEnterTransformation.getMatrix()); } } mSnapshotFinalMatrix.setConcat(mExitTransformation.getMatrix(), mSnapshotInitialMatrix); setSnapshotTransform(mSnapshotFinalMatrix, mExitTransformation.getAlpha()); - return moreEnter || moreExit; + final boolean more = moreStartEnter || moreStartExit || moreFinishEnter || moreFinishExit + || moreRotateEnter || moreRotateExit || !mFinishAnimReady; + + if (DEBUG_STATE) Slog.v(TAG, "Step: more=" + more); + + return more; } public Transformation getEnterTransformation() { diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java index a702ce8f7536..aad562cb3bdf 100644 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -3446,7 +3446,7 @@ public class WindowManagerService extends IWindowManager.Stub // the value of the previous configuration. mTempConfiguration.setToDefaults(); mTempConfiguration.fontScale = currentConfig.fontScale; - if (computeNewConfigurationLocked(mTempConfiguration)) { + if (computeScreenConfigurationLocked(mTempConfiguration)) { if (currentConfig.diff(mTempConfiguration) != 0) { mWaitingForConfig = true; mLayoutNeeded = true; @@ -5362,6 +5362,14 @@ public class WindowManagerService extends IWindowManager.Stub startFreezingDisplayLocked(inTransaction); mInputManager.setDisplayOrientation(0, rotation); + // We need to update our screen size information to match the new + // rotation. Note that this is redundant with the later call to + // sendNewConfiguration() that must be called after this function + // returns... however we need to do the screen size part of that + // before then so we have the correct size to use when initializiation + // the rotation animation for the new rotation. + computeScreenConfigurationLocked(null); + if (!inTransaction) { if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setRotationUnchecked"); @@ -5372,7 +5380,11 @@ public class WindowManagerService extends IWindowManager.Stub // it doesn't support hardware OpenGL emulation yet. if (CUSTOM_SCREEN_ROTATION && mScreenRotationAnimation != null && mScreenRotationAnimation.hasScreenshot()) { - mScreenRotationAnimation.setRotation(rotation); + if (mScreenRotationAnimation.setRotation(rotation, mFxSession, + MAX_ANIMATION_DURATION, mTransitionAnimationScale, + mCurDisplayWidth, mCurDisplayHeight)) { + requestAnimationLocked(0); + } } Surface.setOrientation(0, rotation); } finally { @@ -5860,7 +5872,7 @@ public class WindowManagerService extends IWindowManager.Stub Configuration computeNewConfigurationLocked() { Configuration config = new Configuration(); config.fontScale = 0; - if (!computeNewConfigurationLocked(config)) { + if (!computeScreenConfigurationLocked(config)) { return null; } return config; @@ -6011,12 +6023,10 @@ public class WindowManagerService extends IWindowManager.Stub return sw; } - boolean computeNewConfigurationLocked(Configuration config) { + boolean computeScreenConfigurationLocked(Configuration config) { if (mDisplay == null) { return false; } - - mInputManager.getInputConfiguration(config); // Use the effective "visual" dimensions based on current rotation final boolean rotated = (mRotation == Surface.ROTATION_90 @@ -6050,13 +6060,17 @@ public class WindowManagerService extends IWindowManager.Stub final int dw = mCurDisplayWidth; final int dh = mCurDisplayHeight; - int orientation = Configuration.ORIENTATION_SQUARE; - if (dw < dh) { - orientation = Configuration.ORIENTATION_PORTRAIT; - } else if (dw > dh) { - orientation = Configuration.ORIENTATION_LANDSCAPE; + if (config != null) { + mInputManager.getInputConfiguration(config); + + int orientation = Configuration.ORIENTATION_SQUARE; + if (dw < dh) { + orientation = Configuration.ORIENTATION_PORTRAIT; + } else if (dw > dh) { + orientation = Configuration.ORIENTATION_LANDSCAPE; + } + config.orientation = orientation; } - config.orientation = orientation; // Update real display metrics. mDisplay.getMetricsWithSize(mRealDisplayMetrics, mCurDisplayWidth, mCurDisplayHeight); @@ -6078,36 +6092,39 @@ public class WindowManagerService extends IWindowManager.Stub mCompatibleScreenScale = CompatibilityInfo.computeCompatibleScaling(dm, mCompatDisplayMetrics); - config.screenWidthDp = (int)(mPolicy.getConfigDisplayWidth(dw, dh, mRotation) - / dm.density); - config.screenHeightDp = (int)(mPolicy.getConfigDisplayHeight(dw, dh, mRotation) - / dm.density); - computeSmallestWidthAndScreenLayout(rotated, dw, dh, dm.density, config); + if (config != null) { + config.screenWidthDp = (int)(mPolicy.getConfigDisplayWidth(dw, dh, mRotation) + / dm.density); + config.screenHeightDp = (int)(mPolicy.getConfigDisplayHeight(dw, dh, mRotation) + / dm.density); + computeSmallestWidthAndScreenLayout(rotated, dw, dh, dm.density, config); - config.compatScreenWidthDp = (int)(config.screenWidthDp / mCompatibleScreenScale); - config.compatScreenHeightDp = (int)(config.screenHeightDp / mCompatibleScreenScale); - config.compatSmallestScreenWidthDp = computeCompatSmallestWidth(rotated, dm, dw, dh); + config.compatScreenWidthDp = (int)(config.screenWidthDp / mCompatibleScreenScale); + config.compatScreenHeightDp = (int)(config.screenHeightDp / mCompatibleScreenScale); + config.compatSmallestScreenWidthDp = computeCompatSmallestWidth(rotated, dm, dw, dh); - // Determine whether a hard keyboard is available and enabled. - boolean hardKeyboardAvailable = config.keyboard != Configuration.KEYBOARD_NOKEYS; - if (hardKeyboardAvailable != mHardKeyboardAvailable) { - mHardKeyboardAvailable = hardKeyboardAvailable; - mHardKeyboardEnabled = hardKeyboardAvailable; + // Determine whether a hard keyboard is available and enabled. + boolean hardKeyboardAvailable = config.keyboard != Configuration.KEYBOARD_NOKEYS; + if (hardKeyboardAvailable != mHardKeyboardAvailable) { + mHardKeyboardAvailable = hardKeyboardAvailable; + mHardKeyboardEnabled = hardKeyboardAvailable; - mH.removeMessages(H.REPORT_HARD_KEYBOARD_STATUS_CHANGE); - mH.sendEmptyMessage(H.REPORT_HARD_KEYBOARD_STATUS_CHANGE); - } - if (!mHardKeyboardEnabled) { - config.keyboard = Configuration.KEYBOARD_NOKEYS; + mH.removeMessages(H.REPORT_HARD_KEYBOARD_STATUS_CHANGE); + mH.sendEmptyMessage(H.REPORT_HARD_KEYBOARD_STATUS_CHANGE); + } + if (!mHardKeyboardEnabled) { + config.keyboard = Configuration.KEYBOARD_NOKEYS; + } + + // Update value of keyboardHidden, hardKeyboardHidden and navigationHidden + // based on whether a hard or soft keyboard is present, whether navigation keys + // are present and the lid switch state. + config.keyboardHidden = Configuration.KEYBOARDHIDDEN_NO; + config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_NO; + config.navigationHidden = Configuration.NAVIGATIONHIDDEN_NO; + mPolicy.adjustConfigurationLw(config); } - // Update value of keyboardHidden, hardKeyboardHidden and navigationHidden - // based on whether a hard or soft keyboard is present, whether navigation keys - // are present and the lid switch state. - config.keyboardHidden = Configuration.KEYBOARDHIDDEN_NO; - config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_NO; - config.navigationHidden = Configuration.NAVIGATIONHIDDEN_NO; - mPolicy.adjustConfigurationLw(config); return true; } @@ -7114,7 +7131,7 @@ public class WindowManagerService extends IWindowManager.Stub boolean configChanged = updateOrientationFromAppTokensLocked(false); mTempConfiguration.setToDefaults(); mTempConfiguration.fontScale = mCurConfiguration.fontScale; - if (computeNewConfigurationLocked(mTempConfiguration)) { + if (computeScreenConfigurationLocked(mTempConfiguration)) { if (mCurConfiguration.diff(mTempConfiguration) != 0) { configChanged = true; } |