diff options
30 files changed, 442 insertions, 531 deletions
diff --git a/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java b/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java index 5cfba3d945cd..395c655ddf7c 100644 --- a/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java +++ b/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java @@ -263,12 +263,12 @@ public final class CameraExtensionCharacteristics { @Override public void onServiceConnected(ComponentName component, IBinder binder) { mProxy = ICameraExtensionsProxyService.Stub.asInterface(binder); - mInitFuture.setStatus(true); try { mSupportsAdvancedExtensions = mProxy.advancedExtensionsSupported(); } catch (RemoteException e) { Log.e(TAG, "Remote IPC failed!"); } + mInitFuture.setStatus(true); } }; ctx.bindService(intent, Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT | diff --git a/core/java/android/view/animation/TranslateAnimation.java b/core/java/android/view/animation/TranslateAnimation.java index ec55a0273999..3365c70b5b34 100644 --- a/core/java/android/view/animation/TranslateAnimation.java +++ b/core/java/android/view/animation/TranslateAnimation.java @@ -57,6 +57,9 @@ public class TranslateAnimation extends Animation { /** @hide */ protected float mToYDelta; + private int mWidth; + private int mParentWidth; + /** * Constructor used when a TranslateAnimation is loaded from a resource. * @@ -179,5 +182,60 @@ public class TranslateAnimation extends Animation { mToXDelta = resolveSize(mToXType, mToXValue, width, parentWidth); mFromYDelta = resolveSize(mFromYType, mFromYValue, height, parentHeight); mToYDelta = resolveSize(mToYType, mToYValue, height, parentHeight); + + mWidth = width; + mParentWidth = parentWidth; + } + + /** + * Checks whether or not the translation is exclusively an x axis translation. + * + * @hide + */ + public boolean isXAxisTransition() { + return mFromXDelta - mToXDelta != 0 && mFromYDelta - mToYDelta == 0; + } + + /** + * Checks whether or not the translation is a full width x axis slide in or out translation. + * + * @hide + */ + public boolean isFullWidthTranslate() { + boolean isXAxisSlideTransition = + isSlideInLeft() || isSlideOutRight() || isSlideInRight() || isSlideOutLeft(); + return mWidth == mParentWidth && isXAxisSlideTransition; + } + + private boolean isSlideInLeft() { + boolean startsOutOfParentOnLeft = mFromXDelta <= -mWidth; + return startsOutOfParentOnLeft && endsXEnclosedWithinParent(); + } + + private boolean isSlideOutRight() { + boolean endOutOfParentOnRight = mToXDelta >= mParentWidth; + return startsXEnclosedWithinParent() && endOutOfParentOnRight; + } + + private boolean isSlideInRight() { + boolean startsOutOfParentOnRight = mFromXDelta >= mParentWidth; + return startsOutOfParentOnRight && endsXEnclosedWithinParent(); + } + + private boolean isSlideOutLeft() { + boolean endOutOfParentOnLeft = mToXDelta <= -mWidth; + return startsXEnclosedWithinParent() && endOutOfParentOnLeft; + } + + private boolean endsXEnclosedWithinParent() { + return mWidth <= mParentWidth + && mToXDelta + mWidth <= mParentWidth + && mToXDelta >= 0; + } + + private boolean startsXEnclosedWithinParent() { + return mWidth <= mParentWidth + && mFromXDelta + mWidth <= mParentWidth + && mFromXDelta >= 0; } } diff --git a/core/res/res/anim-ldrtl/cross_profile_apps_thumbnail_enter.xml b/core/res/res/anim-ldrtl/cross_profile_apps_thumbnail_enter.xml index 5add19bba51b..941df96cb941 100644 --- a/core/res/res/anim-ldrtl/cross_profile_apps_thumbnail_enter.xml +++ b/core/res/res/anim-ldrtl/cross_profile_apps_thumbnail_enter.xml @@ -18,19 +18,10 @@ --> <!-- This should be kept in sync with task_open_enter.xml --> <set xmlns:android="http://schemas.android.com/apk/res/android" - android:hasRoundedCorners="true" android:shareInterpolator="false" - android:zAdjustment="top"> - - <alpha - android:fromAlpha="1" - android:toAlpha="1.0" - android:fillEnabled="true" - android:fillBefore="true" - android:fillAfter="true" - android:interpolator="@interpolator/linear" - android:startOffset="67" - android:duration="217"/> + android:zAdjustment="top" + android:hasRoundedCorners="true" + android:background="@color/overview_background"> <translate android:fromXDelta="-105%" @@ -38,36 +29,9 @@ android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true" - android:interpolator="@interpolator/aggressive_ease" - android:startOffset="50" - android:duration="383"/> - - <scale - android:fromXScale="1.0526" - android:toXScale="1" - android:fromYScale="1.0526" - android:toYScale="1" - android:pivotX="50%" - android:pivotY="50%" - android:fillEnabled="true" - android:fillBefore="true" - android:fillAfter="true" - android:interpolator="@interpolator/fast_out_slow_in" - android:duration="283"/> - - <scale - android:fromXScale="0.95" - android:toXScale="1" - android:fromYScale="0.95" - android:toYScale="1" - android:pivotX="50%" - android:pivotY="50%" - android:fillEnabled="true" - android:fillBefore="true" - android:fillAfter="true" - android:interpolator="@interpolator/fast_out_slow_in" - android:startOffset="283" - android:duration="317"/> + android:interpolator="@interpolator/fast_out_extra_slow_in" + android:startOffset="0" + android:duration="500"/> <!-- To keep the thumbnail around longer and fade out the thumbnail --> <alpha android:fromAlpha="1.0" android:toAlpha="0" diff --git a/core/res/res/anim-ldrtl/task_close_enter.xml b/core/res/res/anim-ldrtl/task_close_enter.xml index e00141a8c155..1994048fa3aa 100644 --- a/core/res/res/anim-ldrtl/task_close_enter.xml +++ b/core/res/res/anim-ldrtl/task_close_enter.xml @@ -14,20 +14,10 @@ ~ limitations under the License --> <set xmlns:android="http://schemas.android.com/apk/res/android" - android:shareInterpolator="false" - android:zAdjustment="top" - android:hasRoundedCorners="true" - android:showWallpaper="true"> - - <alpha - android:fromAlpha="1" - android:toAlpha="1.0" - android:fillEnabled="true" - android:fillBefore="true" - android:fillAfter="true" - android:interpolator="@interpolator/linear" - android:startOffset="67" - android:duration="217"/> + android:shareInterpolator="false" + android:zAdjustment="top" + android:hasRoundedCorners="true" + android:background="@color/overview_background"> <translate android:fromXDelta="105%" @@ -35,34 +25,7 @@ android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true" - android:interpolator="@interpolator/aggressive_ease" - android:startOffset="50" - android:duration="383"/> - - <scale - android:fromXScale="1.0526" - android:toXScale="1" - android:fromYScale="1.0526" - android:toYScale="1" - android:pivotX="50%" - android:pivotY="50%" - android:fillEnabled="true" - android:fillBefore="true" - android:fillAfter="true" - android:interpolator="@interpolator/fast_out_slow_in" - android:duration="283"/> - - <scale - android:fromXScale="0.95" - android:toXScale="1" - android:fromYScale="0.95" - android:toYScale="1" - android:pivotX="50%" - android:pivotY="50%" - android:fillEnabled="true" - android:fillBefore="true" - android:fillAfter="true" - android:interpolator="@interpolator/fast_out_slow_in" - android:startOffset="283" - android:duration="317"/> + android:interpolator="@interpolator/fast_out_extra_slow_in" + android:startOffset="0" + android:duration="500"/> </set>
\ No newline at end of file diff --git a/core/res/res/anim-ldrtl/task_close_exit.xml b/core/res/res/anim-ldrtl/task_close_exit.xml index 71a44ae7d2fc..8c0aaa817430 100644 --- a/core/res/res/anim-ldrtl/task_close_exit.xml +++ b/core/res/res/anim-ldrtl/task_close_exit.xml @@ -15,19 +15,9 @@ --> <set xmlns:android="http://schemas.android.com/apk/res/android" - android:shareInterpolator="false" - android:hasRoundedCorners="true" - android:showWallpaper="true"> - - <alpha - android:fromAlpha="1.0" - android:toAlpha="1" - android:fillEnabled="true" - android:fillBefore="true" - android:fillAfter="true" - android:interpolator="@interpolator/linear" - android:startOffset="67" - android:duration="283"/> + android:shareInterpolator="false" + android:hasRoundedCorners="true" + android:background="@color/overview_background"> <translate android:fromXDelta="0" @@ -35,22 +25,9 @@ android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true" - android:interpolator="@interpolator/aggressive_ease" - android:startOffset="50" - android:duration="383"/> - - <scale - android:fromXScale="1.0" - android:toXScale="0.95" - android:fromYScale="1.0" - android:toYScale="0.95" - android:fillEnabled="true" - android:fillBefore="true" - android:fillAfter="true" - android:pivotX="50%" - android:pivotY="50%" - android:interpolator="@interpolator/fast_out_slow_in" - android:duration="283"/> + android:interpolator="@interpolator/fast_out_extra_slow_in" + android:startOffset="0" + android:duration="500"/> <!-- This is needed to keep the animation running while task_open_enter completes --> <alpha diff --git a/core/res/res/anim-ldrtl/task_open_enter.xml b/core/res/res/anim-ldrtl/task_open_enter.xml index 7815f7d661d0..fb7741c8d398 100644 --- a/core/res/res/anim-ldrtl/task_open_enter.xml +++ b/core/res/res/anim-ldrtl/task_open_enter.xml @@ -16,20 +16,10 @@ <!-- This should in sync with task_open_enter_cross_profile_apps.xml --> <!-- This should in sync with cross_profile_apps_thumbnail_enter.xml --> <set xmlns:android="http://schemas.android.com/apk/res/android" - android:shareInterpolator="false" - android:zAdjustment="top" - android:hasRoundedCorners="true" - android:showWallpaper="true"> - - <alpha - android:fromAlpha="1" - android:toAlpha="1.0" - android:fillEnabled="true" - android:fillBefore="true" - android:fillAfter="true" - android:interpolator="@interpolator/linear" - android:startOffset="67" - android:duration="217"/> + android:shareInterpolator="false" + android:zAdjustment="top" + android:hasRoundedCorners="true" + android:background="@color/overview_background"> <translate android:fromXDelta="-105%" @@ -37,34 +27,7 @@ android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true" - android:interpolator="@interpolator/aggressive_ease" - android:startOffset="50" - android:duration="383"/> - - <scale - android:fromXScale="1.0526" - android:toXScale="1" - android:fromYScale="1.0526" - android:toYScale="1" - android:pivotX="50%" - android:pivotY="50%" - android:fillEnabled="true" - android:fillBefore="true" - android:fillAfter="true" - android:interpolator="@interpolator/fast_out_slow_in" - android:duration="283"/> - - <scale - android:fromXScale="0.95" - android:toXScale="1" - android:fromYScale="0.95" - android:toYScale="1" - android:pivotX="50%" - android:pivotY="50%" - android:fillEnabled="true" - android:fillBefore="true" - android:fillAfter="true" - android:interpolator="@interpolator/fast_out_slow_in" - android:startOffset="283" - android:duration="317"/> -</set>
\ No newline at end of file + android:interpolator="@interpolator/fast_out_extra_slow_in" + android:startOffset="0" + android:duration="500"/> +</set> diff --git a/core/res/res/anim-ldrtl/task_open_enter_cross_profile_apps.xml b/core/res/res/anim-ldrtl/task_open_enter_cross_profile_apps.xml index 5fccd6df14a5..69631f6525e3 100644 --- a/core/res/res/anim-ldrtl/task_open_enter_cross_profile_apps.xml +++ b/core/res/res/anim-ldrtl/task_open_enter_cross_profile_apps.xml @@ -16,20 +16,10 @@ --> <!-- This should in sync with task_open_enter.xml --> <set xmlns:android="http://schemas.android.com/apk/res/android" - android:shareInterpolator="false" - android:zAdjustment="top" - android:hasRoundedCorners="true" - android:showWallpaper="true"> - - <alpha - android:fromAlpha="1" - android:toAlpha="1.0" - android:fillEnabled="true" - android:fillBefore="true" - android:fillAfter="true" - android:interpolator="@interpolator/linear" - android:startOffset="67" - android:duration="217"/> + android:shareInterpolator="false" + android:zAdjustment="top" + android:hasRoundedCorners="true" + android:background="@color/overview_background"> <translate android:fromXDelta="-105%" @@ -37,36 +27,9 @@ android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true" - android:interpolator="@interpolator/aggressive_ease" - android:startOffset="50" - android:duration="383"/> - - <scale - android:fromXScale="1.0526" - android:toXScale="1" - android:fromYScale="1.0526" - android:toYScale="1" - android:pivotX="50%" - android:pivotY="50%" - android:fillEnabled="true" - android:fillBefore="true" - android:fillAfter="true" - android:interpolator="@interpolator/fast_out_slow_in" - android:duration="283"/> - - <scale - android:fromXScale="0.95" - android:toXScale="1" - android:fromYScale="0.95" - android:toYScale="1" - android:pivotX="50%" - android:pivotY="50%" - android:fillEnabled="true" - android:fillBefore="true" - android:fillAfter="true" - android:interpolator="@interpolator/fast_out_slow_in" - android:startOffset="283" - android:duration="317"/> + android:interpolator="@interpolator/fast_out_extra_slow_in" + android:startOffset="0" + android:duration="500"/> <!-- To keep the transition around longer for the thumbnail, should be kept in sync with cross_profile_apps_thumbmail.xml --> @@ -75,4 +38,4 @@ android:toAlpha="1.0" android:startOffset="717" android:duration="200"/> -</set>
\ No newline at end of file +</set> diff --git a/core/res/res/anim-ldrtl/task_open_exit.xml b/core/res/res/anim-ldrtl/task_open_exit.xml index 025e1bdc05c9..f455334ced78 100644 --- a/core/res/res/anim-ldrtl/task_open_exit.xml +++ b/core/res/res/anim-ldrtl/task_open_exit.xml @@ -15,19 +15,9 @@ --> <set xmlns:android="http://schemas.android.com/apk/res/android" - android:shareInterpolator="false" - android:hasRoundedCorners="true" - android:showWallpaper="true"> - - <alpha - android:fromAlpha="1.0" - android:toAlpha="1" - android:fillEnabled="true" - android:fillBefore="true" - android:fillAfter="true" - android:interpolator="@interpolator/linear" - android:startOffset="67" - android:duration="283"/> + android:shareInterpolator="false" + android:hasRoundedCorners="true" + android:background="@color/overview_background"> <translate android:fromXDelta="0" @@ -35,22 +25,9 @@ android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true" - android:interpolator="@interpolator/aggressive_ease" - android:startOffset="50" - android:duration="383"/> - - <scale - android:fromXScale="1.0" - android:toXScale="0.95" - android:fromYScale="1.0" - android:toYScale="0.95" - android:fillEnabled="true" - android:fillBefore="true" - android:fillAfter="true" - android:pivotX="50%" - android:pivotY="50%" - android:interpolator="@interpolator/fast_out_slow_in" - android:duration="283"/> + android:interpolator="@interpolator/fast_out_extra_slow_in" + android:startOffset="0" + android:duration="500"/> <!-- This is needed to keep the animation running while task_open_enter completes --> <alpha diff --git a/core/res/res/anim/cross_profile_apps_thumbnail_enter.xml b/core/res/res/anim/cross_profile_apps_thumbnail_enter.xml index 2cfeecf4685d..a495aa1b47ab 100644 --- a/core/res/res/anim/cross_profile_apps_thumbnail_enter.xml +++ b/core/res/res/anim/cross_profile_apps_thumbnail_enter.xml @@ -19,18 +19,9 @@ <!-- This should be kept in sync with task_open_enter.xml --> <set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="false" + android:zAdjustment="top" android:hasRoundedCorners="true" - android:zAdjustment="top"> - - <alpha - android:fromAlpha="1" - android:toAlpha="1.0" - android:fillEnabled="true" - android:fillBefore="true" - android:fillAfter="true" - android:interpolator="@interpolator/linear" - android:startOffset="67" - android:duration="217"/> + android:background="@color/overview_background"> <translate android:fromXDelta="105%" @@ -38,36 +29,9 @@ android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true" - android:interpolator="@interpolator/aggressive_ease" - android:startOffset="50" - android:duration="383"/> - - <scale - android:fromXScale="1.0526" - android:toXScale="1" - android:fromYScale="1.0526" - android:toYScale="1" - android:pivotX="50%" - android:pivotY="50%" - android:fillEnabled="true" - android:fillBefore="true" - android:fillAfter="true" - android:interpolator="@interpolator/fast_out_slow_in" - android:duration="283"/> - - <scale - android:fromXScale="0.95" - android:toXScale="1" - android:fromYScale="0.95" - android:toYScale="1" - android:pivotX="50%" - android:pivotY="50%" - android:fillEnabled="true" - android:fillBefore="true" - android:fillAfter="true" - android:interpolator="@interpolator/fast_out_slow_in" - android:startOffset="283" - android:duration="317"/> + android:interpolator="@interpolator/fast_out_extra_slow_in" + android:startOffset="0" + android:duration="500"/> <!-- To keep the thumbnail around longer and fade out the thumbnail --> <alpha android:fromAlpha="1.0" android:toAlpha="0" diff --git a/core/res/res/anim/task_close_enter.xml b/core/res/res/anim/task_close_enter.xml index 487ff5c748d3..ec6e03b84e04 100644 --- a/core/res/res/anim/task_close_enter.xml +++ b/core/res/res/anim/task_close_enter.xml @@ -16,20 +16,10 @@ */ --> <set xmlns:android="http://schemas.android.com/apk/res/android" - android:shareInterpolator="false" - android:zAdjustment="top" - android:hasRoundedCorners="true" - android:showWallpaper="true"> - - <alpha - android:fromAlpha="1" - android:toAlpha="1.0" - android:fillEnabled="true" - android:fillBefore="true" - android:fillAfter="true" - android:interpolator="@interpolator/linear" - android:startOffset="67" - android:duration="217"/> + android:shareInterpolator="false" + android:zAdjustment="top" + android:hasRoundedCorners="true" + android:background="@color/overview_background"> <translate android:fromXDelta="-105%" @@ -37,34 +27,7 @@ android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true" - android:interpolator="@interpolator/aggressive_ease" - android:startOffset="50" - android:duration="383"/> - - <scale - android:fromXScale="1.0526" - android:toXScale="1" - android:fromYScale="1.0526" - android:toYScale="1" - android:pivotX="50%" - android:pivotY="50%" - android:fillEnabled="true" - android:fillBefore="true" - android:fillAfter="true" - android:interpolator="@interpolator/fast_out_slow_in" - android:duration="283"/> - - <scale - android:fromXScale="0.95" - android:toXScale="1" - android:fromYScale="0.95" - android:toYScale="1" - android:pivotX="50%" - android:pivotY="50%" - android:fillEnabled="true" - android:fillBefore="true" - android:fillAfter="true" - android:interpolator="@interpolator/fast_out_slow_in" - android:startOffset="283" - android:duration="317"/> + android:interpolator="@interpolator/fast_out_extra_slow_in" + android:startOffset="0" + android:duration="500"/> </set>
\ No newline at end of file diff --git a/core/res/res/anim/task_close_exit.xml b/core/res/res/anim/task_close_exit.xml index afc3256cb617..4b1e89ca0e3a 100644 --- a/core/res/res/anim/task_close_exit.xml +++ b/core/res/res/anim/task_close_exit.xml @@ -17,19 +17,9 @@ --> <set xmlns:android="http://schemas.android.com/apk/res/android" - android:shareInterpolator="false" - android:hasRoundedCorners="true" - android:showWallpaper="true"> - - <alpha - android:fromAlpha="1.0" - android:toAlpha="1" - android:fillEnabled="true" - android:fillBefore="true" - android:fillAfter="true" - android:interpolator="@interpolator/linear" - android:startOffset="67" - android:duration="283"/> + android:shareInterpolator="false" + android:hasRoundedCorners="true" + android:background="@color/overview_background"> <translate android:fromXDelta="0" @@ -37,22 +27,9 @@ android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true" - android:interpolator="@interpolator/aggressive_ease" - android:startOffset="50" - android:duration="383"/> - - <scale - android:fromXScale="1.0" - android:toXScale="0.95" - android:fromYScale="1.0" - android:toYScale="0.95" - android:fillEnabled="true" - android:fillBefore="true" - android:fillAfter="true" - android:pivotX="50%" - android:pivotY="50%" - android:interpolator="@interpolator/fast_out_slow_in" - android:duration="283"/> + android:interpolator="@interpolator/fast_out_extra_slow_in" + android:startOffset="0" + android:duration="500"/> <!-- This is needed to keep the animation running while task_open_enter completes --> <alpha diff --git a/core/res/res/anim/task_open_enter.xml b/core/res/res/anim/task_open_enter.xml index 0aafc1c0b91c..d5384463ffff 100644 --- a/core/res/res/anim/task_open_enter.xml +++ b/core/res/res/anim/task_open_enter.xml @@ -15,23 +15,13 @@ ** limitations under the License. */ --> -<!-- This should in sync with task_open_enter_cross_profile_apps.xml --> -<!-- This should in sync with cross_profile_apps_thumbnail_enter.xml --> +<!-- This should be kept in sync with task_open_enter_cross_profile_apps.xml --> +<!-- This should be kept in sync with cross_profile_apps_thumbnail_enter.xml --> <set xmlns:android="http://schemas.android.com/apk/res/android" - android:shareInterpolator="false" - android:zAdjustment="top" - android:hasRoundedCorners="true" - android:showWallpaper="true"> - - <alpha - android:fromAlpha="1" - android:toAlpha="1.0" - android:fillEnabled="true" - android:fillBefore="true" - android:fillAfter="true" - android:interpolator="@interpolator/linear" - android:startOffset="67" - android:duration="217"/> + android:shareInterpolator="false" + android:zAdjustment="top" + android:hasRoundedCorners="true" + android:background="@color/overview_background"> <translate android:fromXDelta="105%" @@ -39,34 +29,7 @@ android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true" - android:interpolator="@interpolator/aggressive_ease" - android:startOffset="50" - android:duration="383"/> - - <scale - android:fromXScale="1.0526" - android:toXScale="1" - android:fromYScale="1.0526" - android:toYScale="1" - android:pivotX="50%" - android:pivotY="50%" - android:fillEnabled="true" - android:fillBefore="true" - android:fillAfter="true" - android:interpolator="@interpolator/fast_out_slow_in" - android:duration="283"/> - - <scale - android:fromXScale="0.95" - android:toXScale="1" - android:fromYScale="0.95" - android:toYScale="1" - android:pivotX="50%" - android:pivotY="50%" - android:fillEnabled="true" - android:fillBefore="true" - android:fillAfter="true" - android:interpolator="@interpolator/fast_out_slow_in" - android:startOffset="283" - android:duration="317"/> + android:interpolator="@interpolator/fast_out_extra_slow_in" + android:startOffset="0" + android:duration="500"/> </set>
\ No newline at end of file diff --git a/core/res/res/anim/task_open_enter_cross_profile_apps.xml b/core/res/res/anim/task_open_enter_cross_profile_apps.xml index 702f7ba162aa..dc316ff20f94 100644 --- a/core/res/res/anim/task_open_enter_cross_profile_apps.xml +++ b/core/res/res/anim/task_open_enter_cross_profile_apps.xml @@ -18,20 +18,10 @@ --> <!-- This should in sync with task_open_enter.xml --> <set xmlns:android="http://schemas.android.com/apk/res/android" - android:shareInterpolator="false" - android:zAdjustment="top" - android:hasRoundedCorners="true" - android:showWallpaper="true"> - - <alpha - android:fromAlpha="1" - android:toAlpha="1.0" - android:fillEnabled="true" - android:fillBefore="true" - android:fillAfter="true" - android:interpolator="@interpolator/linear" - android:startOffset="67" - android:duration="217"/> + android:shareInterpolator="false" + android:zAdjustment="top" + android:hasRoundedCorners="true" + android:background="@color/overview_background"> <translate android:fromXDelta="105%" @@ -39,36 +29,9 @@ android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true" - android:interpolator="@interpolator/aggressive_ease" - android:startOffset="50" - android:duration="383"/> - - <scale - android:fromXScale="1.0526" - android:toXScale="1" - android:fromYScale="1.0526" - android:toYScale="1" - android:pivotX="50%" - android:pivotY="50%" - android:fillEnabled="true" - android:fillBefore="true" - android:fillAfter="true" - android:interpolator="@interpolator/fast_out_slow_in" - android:duration="283"/> - - <scale - android:fromXScale="0.95" - android:toXScale="1" - android:fromYScale="0.95" - android:toYScale="1" - android:pivotX="50%" - android:pivotY="50%" - android:fillEnabled="true" - android:fillBefore="true" - android:fillAfter="true" - android:interpolator="@interpolator/fast_out_slow_in" - android:startOffset="283" - android:duration="317"/> + android:interpolator="@interpolator/fast_out_extra_slow_in" + android:startOffset="0" + android:duration="500"/> <!-- To keep the transition around longer for the thumbnail, should be kept in sync with cross_profile_apps_thumbmail.xml --> diff --git a/core/res/res/anim/task_open_exit.xml b/core/res/res/anim/task_open_exit.xml index 691317d2e6e0..f8ab65517d5a 100644 --- a/core/res/res/anim/task_open_exit.xml +++ b/core/res/res/anim/task_open_exit.xml @@ -17,19 +17,9 @@ --> <set xmlns:android="http://schemas.android.com/apk/res/android" - android:shareInterpolator="false" - android:hasRoundedCorners="true" - android:showWallpaper="true"> - - <alpha - android:fromAlpha="1.0" - android:toAlpha="1" - android:fillEnabled="true" - android:fillBefore="true" - android:fillAfter="true" - android:interpolator="@interpolator/linear" - android:startOffset="67" - android:duration="283"/> + android:shareInterpolator="false" + android:hasRoundedCorners="true" + android:background="@color/overview_background"> <translate android:fromXDelta="0" @@ -37,22 +27,9 @@ android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true" - android:interpolator="@interpolator/aggressive_ease" - android:startOffset="50" - android:duration="383"/> - - <scale - android:fromXScale="1.0" - android:toXScale="0.95" - android:fromYScale="1.0" - android:toYScale="0.95" - android:fillEnabled="true" - android:fillBefore="true" - android:fillAfter="true" - android:pivotX="50%" - android:pivotY="50%" - android:interpolator="@interpolator/fast_out_slow_in" - android:duration="283"/> + android:interpolator="@interpolator/fast_out_extra_slow_in" + android:startOffset="0" + android:duration="500"/> <!-- This is needed to keep the animation running while task_open_enter completes --> <alpha diff --git a/core/res/res/color/overview_background.xml b/core/res/res/color/overview_background.xml new file mode 100644 index 000000000000..45c6c256d67a --- /dev/null +++ b/core/res/res/color/overview_background.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2021 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. + --> +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:color="@android:color/system_neutral2_500" android:lStar="87" /> +</selector>
\ No newline at end of file diff --git a/core/res/res/color/overview_background_dark.xml b/core/res/res/color/overview_background_dark.xml new file mode 100644 index 000000000000..84f4fdff4e1a --- /dev/null +++ b/core/res/res/color/overview_background_dark.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2021 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. + --> +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:color="@android:color/system_neutral2_500" android:lStar="35" /> +</selector>
\ No newline at end of file diff --git a/core/res/res/values-night/colors.xml b/core/res/res/values-night/colors.xml index 2e4578c39430..783fabe20a6d 100644 --- a/core/res/res/values-night/colors.xml +++ b/core/res/res/values-night/colors.xml @@ -33,4 +33,6 @@ <color name="call_notification_answer_color">#5DBA80</color> <color name="personal_apps_suspension_notification_color">#8AB4F8</color> + + <color name="overview_background">@color/overview_background_dark</color> </resources> diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java index 4f3ec96968b2..63f1985aa86e 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java @@ -303,13 +303,13 @@ public class PipController implements PipTransitionController.PipTransitionCallb mOneHandedController = oneHandedController; mPipTransitionController = pipTransitionController; mTaskStackListener = taskStackListener; - mPipInputConsumer = new PipInputConsumer(WindowManagerGlobal.getWindowManagerService(), - INPUT_CONSUMER_PIP, mainExecutor); //TODO: move this to ShellInit when PipController can be injected mMainExecutor.execute(this::init); } public void init() { + mPipInputConsumer = new PipInputConsumer(WindowManagerGlobal.getWindowManagerService(), + INPUT_CONSUMER_PIP, mMainExecutor); mPipTransitionController.registerPipTransitionCallback(this); mPipTaskOrganizer.registerOnDisplayIdChangeCallback((int displayId) -> { mPipBoundsState.setDisplayId(displayId); diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java index 5d37bff192eb..8e6eb02bb6f6 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java @@ -607,6 +607,7 @@ public class NavigationBar implements View.OnAttachStateChangeListener, } public void destroyView() { + setAutoHideController(/* autoHideController */ null); mCommandQueue.removeCallback(this); mContext.getSystemService(WindowManager.class).removeViewImmediate( mNavigationBarView.getRootView()); @@ -946,6 +947,11 @@ public class NavigationBar implements View.OnAttachStateChangeListener, @Override public void onRotationProposal(final int rotation, boolean isValid) { + // The CommandQueue callbacks are added when the view is created to ensure we track other + // states, but until the view is attached (at the next traversal), the view's display is + // not valid. Just ignore the rotation in this case. + if (!mNavigationBarView.isAttachedToWindow()) return; + final int winRotation = mNavigationBarView.getDisplay().getRotation(); final boolean rotateSuggestionsDisabled = RotationButtonController .hasDisable2RotateSuggestionFlag(mDisabledFlags2); @@ -1525,7 +1531,7 @@ public class NavigationBar implements View.OnAttachStateChangeListener, } /** Sets {@link AutoHideController} to the navigation bar. */ - public void setAutoHideController(AutoHideController autoHideController) { + private void setAutoHideController(AutoHideController autoHideController) { mAutoHideController = autoHideController; if (mAutoHideController != null) { mAutoHideController.setNavigationBar(mAutoHideUiElement); diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java index b9e9240b354a..1628c71ae005 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java @@ -395,7 +395,6 @@ public class NavigationBarController implements Callbacks, void removeNavigationBar(int displayId) { NavigationBar navBar = mNavigationBars.get(displayId); if (navBar != null) { - navBar.setAutoHideController(/* autoHideController */ null); navBar.destroyView(); mNavigationBars.remove(displayId); } diff --git a/services/core/java/com/android/server/location/provider/LocationProviderManager.java b/services/core/java/com/android/server/location/provider/LocationProviderManager.java index 62d8c320a13c..05999ae13b8d 100644 --- a/services/core/java/com/android/server/location/provider/LocationProviderManager.java +++ b/services/core/java/com/android/server/location/provider/LocationProviderManager.java @@ -1960,11 +1960,6 @@ public class LocationProviderManager extends Preconditions.checkState(Thread.holdsLock(mLock)); } - if (mDelayedRegister != null) { - mAlarmHelper.cancel(mDelayedRegister); - mDelayedRegister = null; - } - // calculate how long the new request should be delayed before sending it off to the // provider, under the assumption that once we send the request off, the provider will // immediately attempt to deliver a new location satisfying that request. @@ -1997,8 +1992,8 @@ public class LocationProviderManager extends public void onAlarm() { synchronized (mLock) { if (mDelayedRegister == this) { - setProviderRequest(newRequest); mDelayedRegister = null; + setProviderRequest(newRequest); } } } @@ -2025,6 +2020,11 @@ public class LocationProviderManager extends @GuardedBy("mLock") void setProviderRequest(ProviderRequest request) { + if (mDelayedRegister != null) { + mAlarmHelper.cancel(mDelayedRegister); + mDelayedRegister = null; + } + EVENT_LOG.logProviderUpdateRequest(mName, request); mProvider.getController().setRequest(request); diff --git a/services/core/java/com/android/server/location/provider/StationaryThrottlingLocationProvider.java b/services/core/java/com/android/server/location/provider/StationaryThrottlingLocationProvider.java index 22a675ad39ab..ad87c45308f8 100644 --- a/services/core/java/com/android/server/location/provider/StationaryThrottlingLocationProvider.java +++ b/services/core/java/com/android/server/location/provider/StationaryThrottlingLocationProvider.java @@ -105,20 +105,15 @@ public final class StationaryThrottlingLocationProvider extends DelegateLocation synchronized (mLock) { mDeviceIdleHelper.addListener(this); - mDeviceIdle = mDeviceIdleHelper.isDeviceIdle(); - mDeviceStationaryHelper.addListener(this); - mDeviceStationary = false; - mDeviceStationaryRealtimeMs = Long.MIN_VALUE; - - onThrottlingChangedLocked(false); + onDeviceIdleChanged(mDeviceIdleHelper.isDeviceIdle()); } } @Override protected void onStop() { synchronized (mLock) { - mDeviceStationaryHelper.removeListener(this); mDeviceIdleHelper.removeListener(this); + onDeviceIdleChanged(false); mIncomingRequest = ProviderRequest.EMPTY_REQUEST; mOutgoingRequest = ProviderRequest.EMPTY_REQUEST; @@ -151,13 +146,26 @@ public final class StationaryThrottlingLocationProvider extends DelegateLocation } mDeviceIdle = deviceIdle; - onThrottlingChangedLocked(false); + + if (deviceIdle) { + // device stationary helper will deliver an immediate listener update + mDeviceStationaryHelper.addListener(this); + } else { + mDeviceStationaryHelper.removeListener(this); + mDeviceStationary = false; + mDeviceStationaryRealtimeMs = Long.MIN_VALUE; + } } } @Override public void onDeviceStationaryChanged(boolean deviceStationary) { synchronized (mLock) { + if (!mDeviceIdle) { + // stationary detection is only registered while idle - ignore late notifications + return; + } + if (mDeviceStationary == deviceStationary) { return; } diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java index bccc52fe350a..ddaaa1eeff4a 100644 --- a/services/core/java/com/android/server/notification/ManagedServices.java +++ b/services/core/java/com/android/server/notification/ManagedServices.java @@ -1536,7 +1536,7 @@ abstract public class ManagedServices { @Override public void onNullBinding(ComponentName name) { Slog.v(TAG, "onNullBinding() called with: name = [" + name + "]"); - mServicesBound.remove(servicesBindingTag); + mContext.unbindService(this); } }; if (!mContext.bindServiceAsUser(intent, diff --git a/services/core/java/com/android/server/wm/SurfaceAnimator.java b/services/core/java/com/android/server/wm/SurfaceAnimator.java index 3c6c23b08091..c7bf8ecfe949 100644 --- a/services/core/java/com/android/server/wm/SurfaceAnimator.java +++ b/services/core/java/com/android/server/wm/SurfaceAnimator.java @@ -59,11 +59,30 @@ class SurfaceAnimator { @VisibleForTesting final Animatable mAnimatable; private final OnAnimationFinishedCallback mInnerAnimationFinishedCallback; + + /** + * Static callback to run on all animations started through this SurfaceAnimator + * when an animation on a Surface is finished or cancelled without restart. + */ @VisibleForTesting @Nullable final OnAnimationFinishedCallback mStaticAnimationFinishedCallback; + + /** + * Callback unique to each animation (i.e. AnimationAdapter). To be run when an animation on a + * Surface is finished or cancelled without restart. + */ + @Nullable + private OnAnimationFinishedCallback mSurfaceAnimationFinishedCallback; + + /** + * The callback is triggered after the SurfaceAnimator sends a cancel call to the underlying + * AnimationAdapter. + * NOTE: Must be called wherever we call onAnimationCancelled on mAnimation. + */ @Nullable - private OnAnimationFinishedCallback mAnimationFinishedCallback; + private Runnable mAnimationCancelledCallback; + private boolean mAnimationStartDelayed; /** @@ -100,7 +119,7 @@ class SurfaceAnimator { return; } final OnAnimationFinishedCallback animationFinishCallback = - mAnimationFinishedCallback; + mSurfaceAnimationFinishedCallback; reset(mAnimatable.getPendingTransaction(), true /* destroyLeash */); if (staticAnimationFinishedCallback != null) { staticAnimationFinishedCallback.onAnimationFinished(type, anim); @@ -130,15 +149,19 @@ class SurfaceAnimator { * This is important as it will start with the leash hidden or visible before * handing it to the component that is responsible to run the animation. * @param animationFinishedCallback The callback being triggered when the animation finishes. + * @param animationCancelledCallback The callback is triggered after the SurfaceAnimator sends a + * cancel call to the underlying AnimationAdapter. */ void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden, @AnimationType int type, @Nullable OnAnimationFinishedCallback animationFinishedCallback, + @Nullable Runnable animationCancelledCallback, @Nullable SurfaceFreezer freezer) { cancelAnimation(t, true /* restarting */, true /* forwardCancel */); mAnimation = anim; mAnimationType = type; - mAnimationFinishedCallback = animationFinishedCallback; + mSurfaceAnimationFinishedCallback = animationFinishedCallback; + mAnimationCancelledCallback = animationCancelledCallback; final SurfaceControl surface = mAnimatable.getSurfaceControl(); if (surface == null) { Slog.w(TAG, "Unable to start animation, surface is null or no children."); @@ -161,14 +184,9 @@ class SurfaceAnimator { } void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden, - @AnimationType int type, - @Nullable OnAnimationFinishedCallback animationFinishedCallback) { - startAnimation(t, anim, hidden, type, animationFinishedCallback, null /* freezer */); - } - - void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden, @AnimationType int type) { - startAnimation(t, anim, hidden, type, null /* animationFinishedCallback */); + startAnimation(t, anim, hidden, type, null /* animationFinishedCallback */, + null /* animationCancelledCallback */, null /* freezer */); } /** @@ -278,7 +296,8 @@ class SurfaceAnimator { mLeash = from.mLeash; mAnimation = from.mAnimation; mAnimationType = from.mAnimationType; - mAnimationFinishedCallback = from.mAnimationFinishedCallback; + mSurfaceAnimationFinishedCallback = from.mSurfaceAnimationFinishedCallback; + mAnimationCancelledCallback = from.mAnimationCancelledCallback; // Cancel source animation, but don't let animation runner cancel the animation. from.cancelAnimation(t, false /* restarting */, false /* forwardCancel */); @@ -306,11 +325,16 @@ class SurfaceAnimator { final SurfaceControl leash = mLeash; final AnimationAdapter animation = mAnimation; final @AnimationType int animationType = mAnimationType; - final OnAnimationFinishedCallback animationFinishedCallback = mAnimationFinishedCallback; + final OnAnimationFinishedCallback animationFinishedCallback = + mSurfaceAnimationFinishedCallback; + final Runnable animationCancelledCallback = mAnimationCancelledCallback; reset(t, false); if (animation != null) { if (!mAnimationStartDelayed && forwardCancel) { animation.onAnimationCancelled(leash); + if (animationCancelledCallback != null) { + animationCancelledCallback.run(); + } } if (!restarting) { if (mStaticAnimationFinishedCallback != null) { @@ -335,7 +359,7 @@ class SurfaceAnimator { private void reset(Transaction t, boolean destroyLeash) { mService.mAnimationTransferMap.remove(mAnimation); mAnimation = null; - mAnimationFinishedCallback = null; + mSurfaceAnimationFinishedCallback = null; mAnimationType = ANIMATION_TYPE_NONE; if (mLeash == null) { return; diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java index d450dbffe4a1..ee4c629189dc 100644 --- a/services/core/java/com/android/server/wm/TaskDisplayArea.java +++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java @@ -42,6 +42,9 @@ import static com.android.server.wm.Task.TASK_VISIBILITY_VISIBLE; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ROOT_TASK; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; +import static java.lang.Integer.MIN_VALUE; + +import android.annotation.ColorInt; import android.annotation.Nullable; import android.app.ActivityOptions; import android.app.WindowConfiguration; @@ -80,6 +83,22 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> { DisplayContent mDisplayContent; /** + * A color layer that serves as a solid color background to certain animations. + */ + private SurfaceControl mColorBackgroundLayer; + + /** + * This counter is used to make sure we don't prematurely clear the background color in the + * case that background color animations are interleaved. + * NOTE: The last set color will remain until the counter is reset to 0, which means that an + * animation background color may sometime remain after the animation has finished through an + * animation with a different background color if an animation starts after and ends before + * another where both set different background colors. However, this is not a concern as + * currently all task animation backgrounds are the same color. + */ + private int mColorLayerCounter = 0; + + /** * A control placed at the appropriate level for transitions to occur. */ private SurfaceControl mAppAnimationLayer; @@ -961,6 +980,11 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> { void onParentChanged(ConfigurationContainer newParent, ConfigurationContainer oldParent) { if (getParent() != null) { super.onParentChanged(newParent, oldParent, () -> { + mColorBackgroundLayer = makeChildSurface(null) + .setColorLayer() + .setName("colorBackgroundLayer") + .setCallsite("TaskDisplayArea.onParentChanged") + .build(); mAppAnimationLayer = makeChildSurface(null) .setName("animationLayer") .setCallsite("TaskDisplayArea.onParentChanged") @@ -977,6 +1001,7 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> { .setName("splitScreenDividerAnchor") .setCallsite("TaskDisplayArea.onParentChanged") .build(); + getSyncTransaction() .show(mAppAnimationLayer) .show(mBoostedAppAnimationLayer) @@ -986,11 +1011,13 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> { } else { super.onParentChanged(newParent, oldParent); mWmService.mTransactionFactory.get() + .remove(mColorBackgroundLayer) .remove(mAppAnimationLayer) .remove(mBoostedAppAnimationLayer) .remove(mHomeAppAnimationLayer) .remove(mSplitScreenDividerAnchor) .apply(); + mColorBackgroundLayer = null; mAppAnimationLayer = null; mBoostedAppAnimationLayer = null; mHomeAppAnimationLayer = null; @@ -998,6 +1025,39 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> { } } + void setBackgroundColor(@ColorInt int color) { + if (mColorBackgroundLayer == null) { + return; + } + + float r = ((color >> 16) & 0xff) / 255.0f; + float g = ((color >> 8) & 0xff) / 255.0f; + float b = ((color >> 0) & 0xff) / 255.0f; + float a = ((color >> 24) & 0xff) / 255.0f; + + mColorLayerCounter++; + + getPendingTransaction().setLayer(mColorBackgroundLayer, MIN_VALUE) + .setColor(mColorBackgroundLayer, new float[]{r, g, b}) + .setAlpha(mColorBackgroundLayer, a) + .setWindowCrop(mColorBackgroundLayer, getSurfaceWidth(), getSurfaceHeight()) + .setPosition(mColorBackgroundLayer, 0, 0) + .show(mColorBackgroundLayer); + + scheduleAnimation(); + } + + void clearBackgroundColor() { + mColorLayerCounter--; + + // Only clear the color layer if we have received the same amounts of clear as set + // requests. + if (mColorLayerCounter == 0) { + getPendingTransaction().hide(mColorBackgroundLayer); + scheduleAnimation(); + } + } + @Override void migrateToNewSurfaceControl(SurfaceControl.Transaction t) { super.migrateToNewSurfaceControl(t); @@ -1006,6 +1066,7 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> { } // As TaskDisplayArea is getting a new surface, reparent and reorder the child surfaces. + t.reparent(mColorBackgroundLayer, mSurfaceControl); t.reparent(mAppAnimationLayer, mSurfaceControl); t.reparent(mBoostedAppAnimationLayer, mSurfaceControl); t.reparent(mHomeAppAnimationLayer, mSurfaceControl); @@ -2149,6 +2210,11 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> { } @Override + TaskDisplayArea getTaskDisplayArea() { + return this; + } + + @Override boolean isTaskDisplayArea() { return true; } diff --git a/services/core/java/com/android/server/wm/WindowAnimationSpec.java b/services/core/java/com/android/server/wm/WindowAnimationSpec.java index 70822eebba82..08758afcb0b2 100644 --- a/services/core/java/com/android/server/wm/WindowAnimationSpec.java +++ b/services/core/java/com/android/server/wm/WindowAnimationSpec.java @@ -125,16 +125,30 @@ public class WindowAnimationSpec implements AnimationSpec { @Override public long calculateStatusBarTransitionStartTime() { TranslateAnimation openTranslateAnimation = findTranslateAnimation(mAnimation); - if (openTranslateAnimation != null) { - // Some interpolators are extremely quickly mostly finished, but not completely. For - // our purposes, we need to find the fraction for which ther interpolator is mostly - // there, and use that value for the calculation. - float t = findAlmostThereFraction(openTranslateAnimation.getInterpolator()); - return SystemClock.uptimeMillis() - + openTranslateAnimation.getStartOffset() - + (long)(openTranslateAnimation.getDuration() * t) - - STATUS_BAR_TRANSITION_DURATION; + if (openTranslateAnimation != null) { + if (openTranslateAnimation.isXAxisTransition() + && openTranslateAnimation.isFullWidthTranslate()) { + // On X axis transitions that are fullscreen (heuristic for task like transitions) + // we want the status bar to animate right in the middle of the translation when + // the windows/tasks have each moved half way across. + float t = findMiddleOfTranslationFraction(openTranslateAnimation.getInterpolator()); + + return SystemClock.uptimeMillis() + + openTranslateAnimation.getStartOffset() + + (long) (openTranslateAnimation.getDuration() * t) + - (long) (STATUS_BAR_TRANSITION_DURATION * 0.5); + } else { + // Some interpolators are extremely quickly mostly finished, but not completely. For + // our purposes, we need to find the fraction for which their interpolator is mostly + // there, and use that value for the calculation. + float t = findAlmostThereFraction(openTranslateAnimation.getInterpolator()); + + return SystemClock.uptimeMillis() + + openTranslateAnimation.getStartOffset() + + (long) (openTranslateAnimation.getDuration() * t) + - STATUS_BAR_TRANSITION_DURATION; + } } else { return SystemClock.uptimeMillis(); } @@ -183,20 +197,39 @@ public class WindowAnimationSpec implements AnimationSpec { } /** - * Binary searches for a {@code t} such that there exists a {@code -0.01 < eps < 0.01} for which - * {@code interpolator(t + eps) > 0.99}. + * Finds the fraction of the animation's duration at which the transition is almost done with a + * maximal error of 0.01 when it is animated with {@code interpolator}. */ private static float findAlmostThereFraction(Interpolator interpolator) { + return findInterpolationAdjustedTargetFraction(interpolator, 0.99f, 0.01f); + } + + /** + * Finds the fraction of the animation's duration at which the transition is spacially half way + * done with a maximal error of 0.01 when it is animated with {@code interpolator}. + */ + private float findMiddleOfTranslationFraction(Interpolator interpolator) { + return findInterpolationAdjustedTargetFraction(interpolator, 0.5f, 0.01f); + } + + /** + * Binary searches for a {@code val} such that there exists an {@code -0.01 < epsilon < 0.01} + * for which {@code interpolator(val + epsilon) > target}. + */ + private static float findInterpolationAdjustedTargetFraction( + Interpolator interpolator, float target, float epsilon) { float val = 0.5f; float adj = 0.25f; - while (adj >= 0.01f) { - if (interpolator.getInterpolation(val) < 0.99f) { + + while (adj >= epsilon) { + if (interpolator.getInterpolation(val) < target) { val += adj; } else { val -= adj; } adj /= 2; } + return val; } diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java index b1c7e196b70c..d9a8883e299e 100644 --- a/services/core/java/com/android/server/wm/WindowContainer.java +++ b/services/core/java/com/android/server/wm/WindowContainer.java @@ -850,6 +850,12 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< return parent != null ? parent.getRootDisplayArea() : null; } + @Nullable + TaskDisplayArea getTaskDisplayArea() { + WindowContainer parent = getParent(); + return parent != null ? parent.getTaskDisplayArea() : null; + } + boolean isAttached() { return getDisplayArea() != null; } @@ -2495,10 +2501,13 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< * some point but the meaning is too weird to work for all containers. * @param type The type of animation defined as {@link AnimationType}. * @param animationFinishedCallback The callback being triggered when the animation finishes. + * @param animationCancelledCallback The callback is triggered after the SurfaceAnimator sends a + * cancel call to the underlying AnimationAdapter. */ void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden, @AnimationType int type, - @Nullable OnAnimationFinishedCallback animationFinishedCallback) { + @Nullable OnAnimationFinishedCallback animationFinishedCallback, + @Nullable Runnable animationCancelledCallback) { if (DEBUG_ANIM) { Slog.v(TAG, "Starting animation on " + this + ": type=" + type + ", anim=" + anim); } @@ -2506,7 +2515,14 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< // TODO: This should use isVisible() but because isVisible has a really weird meaning at // the moment this doesn't work for all animatable window containers. mSurfaceAnimator.startAnimation(t, anim, hidden, type, animationFinishedCallback, - mSurfaceFreezer); + animationCancelledCallback, mSurfaceFreezer); + } + + void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden, + @AnimationType int type, + @Nullable OnAnimationFinishedCallback animationFinishedCallback) { + startAnimation(t, anim, hidden, type, animationFinishedCallback, + null /* adapterAnimationCancelledCallback */); } void startAnimation(Transaction t, AnimationAdapter anim, boolean hidden, @@ -2714,8 +2730,27 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< if (sources != null) { mSurfaceAnimationSources.addAll(sources); } + + TaskDisplayArea taskDisplayArea = getTaskDisplayArea(); + int backgroundColor = adapter.getBackgroundColor(); + + boolean shouldSetBackgroundColor = taskDisplayArea != null && backgroundColor != 0; + + if (shouldSetBackgroundColor) { + taskDisplayArea.setBackgroundColor(backgroundColor); + } + + Runnable clearColorBackground = () -> { + if (shouldSetBackgroundColor) { + taskDisplayArea.clearBackgroundColor(); + } + }; + startAnimation(getPendingTransaction(), adapter, !isVisible(), - ANIMATION_TYPE_APP_TRANSITION); + ANIMATION_TYPE_APP_TRANSITION, + (type, anim) -> clearColorBackground.run(), + clearColorBackground); + if (adapter.getShowWallpaper()) { getDisplayContent().pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER; } diff --git a/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java b/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java index f703e2e59181..d0b2edadc714 100644 --- a/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java @@ -906,6 +906,21 @@ public class LocationProviderManagerTest { } @Test + public void testProviderRequest_DelayedRequest_Remove() { + mProvider.setProviderLocation(createLocation(NAME, mRandom)); + + ILocationListener listener1 = createMockLocationListener(); + LocationRequest request1 = new LocationRequest.Builder(60000) + .setWorkSource(WORK_SOURCE) + .build(); + mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1); + mManager.unregisterLocationRequest(listener1); + + mInjector.getAlarmHelper().incrementAlarmTime(60000); + assertThat(mProvider.getRequest().isActive()).isFalse(); + } + + @Test public void testProviderRequest_SpamRequesting() { mProvider.setProviderLocation(createLocation(NAME, mRandom)); diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java index f9663f200b56..987236c7c98c 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java @@ -65,6 +65,7 @@ import com.google.android.collect.Lists; import org.junit.Before; import org.junit.Test; +import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.invocation.InvocationOnMock; @@ -1320,16 +1321,15 @@ public class ManagedServicesTest extends UiServiceTestCase { APPROVAL_BY_COMPONENT); ComponentName cn = ComponentName.unflattenFromString("a/a"); - service.registerSystemService(cn, 0); - when(context.bindServiceAsUser(any(), any(), anyInt(), any())).thenAnswer(invocation -> { - Object[] args = invocation.getArguments(); - ServiceConnection sc = (ServiceConnection) args[1]; - sc.onNullBinding(cn); - return true; - }); + ArgumentCaptor<ServiceConnection> captor = ArgumentCaptor.forClass(ServiceConnection.class); + when(context.bindServiceAsUser(any(), captor.capture(), anyInt(), any())) + .thenAnswer(invocation -> { + captor.getValue().onNullBinding(cn); + return true; + }); service.registerSystemService(cn, 0); - assertFalse(service.isBound(cn, 0)); + verify(context).unbindService(captor.getValue()); } @Test diff --git a/telephony/java/android/telephony/SignalStrengthUpdateRequest.java b/telephony/java/android/telephony/SignalStrengthUpdateRequest.java index fe7e5976b132..41e24ddb3fa6 100644 --- a/telephony/java/android/telephony/SignalStrengthUpdateRequest.java +++ b/telephony/java/android/telephony/SignalStrengthUpdateRequest.java @@ -26,8 +26,10 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; +import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Set; @@ -101,9 +103,11 @@ public final class SignalStrengthUpdateRequest implements Parcelable { } mSignalThresholdInfos = new ArrayList<>(signalThresholdInfos); - // Sort the collection with RAN ascending order, make the ordering not matter for equals + // Sort the collection with RAN and then SignalMeasurementType ascending order, make the + // ordering not matter for equals mSignalThresholdInfos.sort( - Comparator.comparingInt(SignalThresholdInfo::getRadioAccessNetworkType)); + Comparator.comparingInt(SignalThresholdInfo::getRadioAccessNetworkType) + .thenComparing(SignalThresholdInfo::getSignalMeasurementType)); return this; } @@ -144,7 +148,7 @@ public final class SignalStrengthUpdateRequest implements Parcelable { * @return the SignalStrengthUpdateRequest object * * @throws IllegalArgumentException if the SignalThresholdInfo collection is empty size, the - * radio access network type in the collection is not unique + * signal measurement type for the same RAN in the collection is not unique */ public @NonNull SignalStrengthUpdateRequest build() { return new SignalStrengthUpdateRequest(mSignalThresholdInfos, @@ -258,14 +262,23 @@ public final class SignalStrengthUpdateRequest implements Parcelable { } /** - * Throw IAE when the RAN in the collection is not unique. + * Throw IAE if SignalThresholdInfo collection is null or empty, + * or the SignalMeasurementType for the same RAN in the collection is not unique. */ private static void validate(Collection<SignalThresholdInfo> infos) { - Set<Integer> uniqueRan = new HashSet<>(infos.size()); + if (infos == null || infos.isEmpty()) { + throw new IllegalArgumentException("SignalThresholdInfo collection is null or empty"); + } + + // Map from RAN to set of SignalMeasurementTypes + Map<Integer, Set<Integer>> ranToTypes = new HashMap<>(infos.size()); for (SignalThresholdInfo info : infos) { final int ran = info.getRadioAccessNetworkType(); - if (!uniqueRan.add(ran)) { - throw new IllegalArgumentException("RAN: " + ran + " is not unique"); + final int type = info.getSignalMeasurementType(); + ranToTypes.putIfAbsent(ran, new HashSet<>()); + if (!ranToTypes.get(ran).add(type)) { + throw new IllegalArgumentException( + "SignalMeasurementType " + type + " for RAN " + ran + " is not unique"); } } } |