diff options
20 files changed, 315 insertions, 631 deletions
diff --git a/core/proto/android/server/animationadapter.proto b/core/proto/android/server/animationadapter.proto index c6925f448a58..70627edf2cb3 100644 --- a/core/proto/android/server/animationadapter.proto +++ b/core/proto/android/server/animationadapter.proto @@ -50,7 +50,6 @@ message AnimationSpecProto { optional WindowAnimationSpecProto window = 1; optional MoveAnimationSpecProto move = 2; optional AlphaAnimationSpecProto alpha = 3; - optional RotationAnimationSpecProto rotate = 4; } /* represents WindowAnimationSpec */ @@ -77,12 +76,3 @@ message AlphaAnimationSpecProto { optional float to = 2; optional int64 duration_ms = 3; } - -/* represents RotationAnimationSpec */ -message RotationAnimationSpecProto { - option (.android.msg_privacy).dest = DEST_AUTOMATIC; - - optional float start_luma = 1; - optional float end_luma = 2; - optional int64 duration_ms = 3; -} diff --git a/core/res/res/anim/screen_rotate_0_enter.xml b/core/res/res/anim/screen_rotate_0_enter.xml index 629be7ea2d30..93cf3652d185 100644 --- a/core/res/res/anim/screen_rotate_0_enter.xml +++ b/core/res/res/anim/screen_rotate_0_enter.xml @@ -1,25 +1,25 @@ <?xml version="1.0" encoding="utf-8"?> <!-- - ~ Copyright (C) 2019 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. - --> +/* +** Copyright 2010, 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"> - <alpha android:fromAlpha="0.0" android:toAlpha="1.0" - android:interpolator="@interpolator/screen_rotation_alpha_in" - android:fillEnabled="true" - android:fillBefore="true" android:fillAfter="true" - android:duration="@android:integer/config_screen_rotation_fade_in" /> + android:shareInterpolator="false"> + <alpha android:fromAlpha="1.0" android:toAlpha="1.0" + android:interpolator="@interpolator/decelerate_quint" + android:duration="@android:integer/config_shortAnimTime" /> </set> diff --git a/core/res/res/anim/screen_rotate_0_exit.xml b/core/res/res/anim/screen_rotate_0_exit.xml index fa046a036855..37d5a4115621 100644 --- a/core/res/res/anim/screen_rotate_0_exit.xml +++ b/core/res/res/anim/screen_rotate_0_exit.xml @@ -1,25 +1,22 @@ <?xml version="1.0" encoding="utf-8"?> <!-- - ~ Copyright (C) 2019 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. - --> +/* +** Copyright 2010, 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"> - <alpha android:fromAlpha="1.0" android:toAlpha="0.0" - android:interpolator="@interpolator/screen_rotation_alpha_out" - android:fillEnabled="true" - android:fillBefore="true" android:fillAfter="true" - android:duration="@android:integer/config_screen_rotation_fade_out" /> + android:shareInterpolator="false"> </set> diff --git a/core/res/res/anim/screen_rotate_0_frame.xml b/core/res/res/anim/screen_rotate_0_frame.xml new file mode 100644 index 000000000000..5ea9bf8205e3 --- /dev/null +++ b/core/res/res/anim/screen_rotate_0_frame.xml @@ -0,0 +1,25 @@ +<?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"> + <alpha android:fromAlpha="1.0" android:toAlpha="1.0" + android:interpolator="@interpolator/decelerate_quint" + android:duration="@android:integer/config_shortAnimTime" /> +</set> diff --git a/core/res/res/anim/screen_rotate_180_enter.xml b/core/res/res/anim/screen_rotate_180_enter.xml index 889a615e07f4..688a8d5bb2aa 100644 --- a/core/res/res/anim/screen_rotate_180_enter.xml +++ b/core/res/res/anim/screen_rotate_180_enter.xml @@ -18,11 +18,11 @@ --> <set xmlns:android="http://schemas.android.com/apk/res/android" - android:shareInterpolator="false"> + android:shareInterpolator="false"> <rotate android:fromDegrees="180" android:toDegrees="0" - android:pivotX="50%" android:pivotY="50%" - android:fillEnabled="true" - android:fillBefore="true" android:fillAfter="true" - android:interpolator="@interpolator/fast_out_slow_in" - android:duration="@android:integer/config_screen_rotation_total_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> diff --git a/core/res/res/anim/screen_rotate_180_exit.xml b/core/res/res/anim/screen_rotate_180_exit.xml index 766fcfae1f91..58a1868bd398 100644 --- a/core/res/res/anim/screen_rotate_180_exit.xml +++ b/core/res/res/anim/screen_rotate_180_exit.xml @@ -18,11 +18,11 @@ --> <set xmlns:android="http://schemas.android.com/apk/res/android" - android:shareInterpolator="false"> + android:shareInterpolator="false"> <rotate android:fromDegrees="0" android:toDegrees="-180" - android:pivotX="50%" android:pivotY="50%" - android:fillEnabled="true" - android:fillBefore="true" android:fillAfter="true" - android:interpolator="@interpolator/fast_out_slow_in" - android:duration="@android:integer/config_screen_rotation_total_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_alpha.xml b/core/res/res/anim/screen_rotate_alpha.xml index 2cac982e24b4..c49ef9cafd39 100644 --- a/core/res/res/anim/screen_rotate_alpha.xml +++ b/core/res/res/anim/screen_rotate_alpha.xml @@ -20,8 +20,8 @@ <set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="false"> <alpha android:fromAlpha="1.0" android:toAlpha="0.0" - android:interpolator="@interpolator/screen_rotation_alpha_out" + android:interpolator="@interpolator/decelerate_quint" android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true" - android:duration="@android:integer/config_screen_rotation_fade_out" /> + 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 87fd25ea4603..b16d5fc761ee 100644 --- a/core/res/res/anim/screen_rotate_minus_90_enter.xml +++ b/core/res/res/anim/screen_rotate_minus_90_enter.xml @@ -18,17 +18,19 @@ --> <set xmlns:android="http://schemas.android.com/apk/res/android" - android:shareInterpolator="false"> + android:shareInterpolator="false"> + <!-- Version for two-phase anim <rotate android:fromDegrees="-90" android:toDegrees="0" - android:pivotX="50%" android:pivotY="50%" - android:fillEnabled="true" - android:fillBefore="true" android:fillAfter="true" - android:interpolator="@interpolator/fast_out_slow_in" - android:duration="@android:integer/config_screen_rotation_total_90" /> - <alpha android:fromAlpha="0.0" android:toAlpha="1.0" - android:fillEnabled="true" - android:fillBefore="true" android:fillAfter="true" - android:interpolator="@interpolator/screen_rotation_alpha_in" - android:startOffset="@android:integer/config_screen_rotation_fade_in_delay" - android:duration="@android:integer/config_screen_rotation_fade_in" /> + 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_longAnimTime" /> + --> + <rotate android:fromDegrees="-90" android:toDegrees="0" + android:pivotX="50%" android:pivotY="50%" + android:fillEnabled="true" + android:fillBefore="true" android:fillAfter="true" + android:interpolator="@interpolator/decelerate_quint" + 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 c3aee14dc235..0927dd30ceb3 100644 --- a/core/res/res/anim/screen_rotate_minus_90_exit.xml +++ b/core/res/res/anim/screen_rotate_minus_90_exit.xml @@ -18,16 +18,26 @@ --> <set xmlns:android="http://schemas.android.com/apk/res/android" - android:shareInterpolator="false"> + android:shareInterpolator="false"> + <!-- Version for two-phase animation <rotate android:fromDegrees="0" android:toDegrees="90" - android:pivotX="50%" android:pivotY="50%" - android:fillEnabled="true" - android:fillBefore="true" android:fillAfter="true" - android:interpolator="@interpolator/fast_out_slow_in" - android:duration="@android:integer/config_screen_rotation_total_90" /> - <alpha android:fromAlpha="1.0" android:toAlpha="0.0" - android:fillEnabled="true" - android:fillBefore="true" android:fillAfter="true" - android:interpolator="@interpolator/screen_rotation_alpha_out" - android:duration="@android:integer/config_screen_rotation_fade_out" /> + 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_longAnimTime" /> + --> + <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:fillEnabled="true" + android:fillBefore="true" 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 8849db421e75..86a8d24cbbcc 100644 --- a/core/res/res/anim/screen_rotate_plus_90_enter.xml +++ b/core/res/res/anim/screen_rotate_plus_90_enter.xml @@ -18,16 +18,19 @@ --> <set xmlns:android="http://schemas.android.com/apk/res/android" - android:shareInterpolator="false"> + android:shareInterpolator="false"> + <!-- Version for two-phase animation <rotate android:fromDegrees="90" android:toDegrees="0" - android:pivotX="50%" android:pivotY="50%" - android:fillEnabled="true" - android:fillBefore="true" android:fillAfter="true" - android:interpolator="@interpolator/fast_out_slow_in" - android:duration="@android:integer/config_screen_rotation_total_90" /> - <alpha android:fromAlpha="0.0" android:toAlpha="1.0" - android:fillEnabled="true" - android:interpolator="@interpolator/screen_rotation_alpha_in" - android:startOffset="@android:integer/config_screen_rotation_fade_in_delay" - android:duration="@android:integer/config_screen_rotation_fade_in" /> + 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_longAnimTime" /> + --> + <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 de84c3bd08fc..fd786f9afce0 100644 --- a/core/res/res/anim/screen_rotate_plus_90_exit.xml +++ b/core/res/res/anim/screen_rotate_plus_90_exit.xml @@ -18,16 +18,26 @@ --> <set xmlns:android="http://schemas.android.com/apk/res/android" - android:shareInterpolator="false"> + android:shareInterpolator="false"> + <!-- Version for two-phase animation <rotate android:fromDegrees="0" android:toDegrees="-90" - android:pivotX="50%" android:pivotY="50%" - android:fillEnabled="true" - android:fillBefore="true" android:fillAfter="true" - android:interpolator="@interpolator/fast_out_slow_in" - android:duration="@android:integer/config_screen_rotation_total_90" /> - <alpha android:fromAlpha="1.0" android:toAlpha="0.0" - android:interpolator="@interpolator/screen_rotation_alpha_out" - android:fillEnabled="true" - android:fillBefore="true" android:fillAfter="true" - android:duration="@android:integer/config_screen_rotation_fade_out" /> + 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_longAnimTime" /> + --> + <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:fillEnabled="true" + android:fillBefore="true" 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/interpolator/screen_rotation_alpha_in.xml b/core/res/res/interpolator/screen_rotation_alpha_in.xml deleted file mode 100644 index 9c566a7c8f23..000000000000 --- a/core/res/res/interpolator/screen_rotation_alpha_in.xml +++ /dev/null @@ -1,22 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - ~ Copyright (C) 2019 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. - --> - -<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android" - android:controlX1="0.15" - android:controlY1="0.45" - android:controlX2="0.33" - android:controlY2="1"/> diff --git a/core/res/res/interpolator/screen_rotation_alpha_out.xml b/core/res/res/interpolator/screen_rotation_alpha_out.xml deleted file mode 100644 index 73a37d4f1aa5..000000000000 --- a/core/res/res/interpolator/screen_rotation_alpha_out.xml +++ /dev/null @@ -1,22 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - ~ Copyright (C) 2019 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. - --> - -<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android" - android:controlX1="0.57" - android:controlY1="0" - android:controlX2="0.71" - android:controlY2=".43"/> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index cd35c16ac902..a66aa2968e9d 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -147,24 +147,6 @@ <integer name="config_activityShortDur">150</integer> <integer name="config_activityDefaultDur">220</integer> - <!-- Fade out time for screen rotation --> - <integer name="config_screen_rotation_fade_out">116</integer> - - <!-- Fade in time for screen rotation --> - <integer name="config_screen_rotation_fade_in">233</integer> - - <!-- Fade in delay time for screen rotation --> - <integer name="config_screen_rotation_fade_in_delay">100</integer> - - <!-- Total time for 90 degree screen rotation animations --> - <integer name="config_screen_rotation_total_90">333</integer> - - <!-- Total time for 180 degree screen rotation animation --> - <integer name="config_screen_rotation_total_180">433</integer> - - <!-- Total time for the rotation background color transition --> - <integer name="config_screen_rotation_color_transition">200</integer> - <!-- The duration (in milliseconds) of the tooltip show/hide animations. --> <integer name="config_tooltipAnimTime">150</integer> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 9af6300001fa..9ad6bad2670c 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -1790,6 +1790,7 @@ <!-- From services --> <java-symbol type="anim" name="screen_rotate_0_enter" /> <java-symbol type="anim" name="screen_rotate_0_exit" /> + <java-symbol type="anim" name="screen_rotate_0_frame" /> <java-symbol type="anim" name="screen_rotate_180_enter" /> <java-symbol type="anim" name="screen_rotate_180_exit" /> <java-symbol type="anim" name="screen_rotate_180_frame" /> @@ -1965,7 +1966,6 @@ <java-symbol type="integer" name="config_virtualKeyQuietTimeMillis" /> <java-symbol type="integer" name="config_brightness_ramp_rate_fast" /> <java-symbol type="integer" name="config_brightness_ramp_rate_slow" /> - <java-symbol type="integer" name="config_screen_rotation_color_transition" /> <java-symbol type="layout" name="am_compat_mode_dialog" /> <java-symbol type="layout" name="launch_warning" /> <java-symbol type="layout" name="safe_mode" /> diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index ce7cf51dc135..d20191dd1f85 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -1287,21 +1287,13 @@ public final class DisplayManagerService extends SystemService { } private SurfaceControl.ScreenshotGraphicBuffer screenshotInternal(int displayId) { - synchronized (mSyncRoot) { - final IBinder token = getDisplayToken(displayId); - if (token == null) { - return null; - } - final LogicalDisplay logicalDisplay = mLogicalDisplays.get(displayId); - if (logicalDisplay == null) { - return null; - } - - final DisplayInfo displayInfo = logicalDisplay.getDisplayInfoLocked(); - return SurfaceControl.screenshotToBufferWithSecureLayersUnsafe(token, new Rect(), - displayInfo.getNaturalWidth(), displayInfo.getNaturalHeight(), - false /* useIdentityTransform */, 0 /* rotation */); + final IBinder token = getDisplayToken(displayId); + if (token == null) { + return null; } + return SurfaceControl.screenshotToBufferWithSecureLayersUnsafe( + token, new Rect(), 0 /* width */, 0 /* height */, + false /* useIdentityTransform */, 0 /* rotation */); } @VisibleForTesting diff --git a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java index eaa0ea72452a..399c5d3ae45f 100644 --- a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java +++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java @@ -16,12 +16,8 @@ package com.android.server.wm; -import static com.android.server.wm.AnimationSpecProto.ROTATE; import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION; import static com.android.server.wm.ProtoLogGroup.WM_SHOW_SURFACE_ALLOC; -import static com.android.server.wm.RotationAnimationSpecProto.DURATION_MS; -import static com.android.server.wm.RotationAnimationSpecProto.END_LUMA; -import static com.android.server.wm.RotationAnimationSpecProto.START_LUMA; import static com.android.server.wm.ScreenRotationAnimationProto.ANIMATION_RUNNING; import static com.android.server.wm.ScreenRotationAnimationProto.STARTED; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; @@ -29,9 +25,7 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import static com.android.server.wm.WindowManagerService.TYPE_LAYER_MULTIPLIER; import static com.android.server.wm.WindowStateAnimator.WINDOW_FREEZE_LAYER; -import android.animation.ArgbEvaluator; import android.content.Context; -import android.graphics.Color; import android.graphics.Matrix; import android.graphics.Point; import android.graphics.Rect; @@ -46,9 +40,7 @@ import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.view.animation.Transformation; -import com.android.internal.R; import com.android.server.protolog.common.ProtoLog; -import com.android.server.wm.utils.RotationAnimationUtils; import java.io.PrintWriter; @@ -68,10 +60,10 @@ import java.io.PrintWriter; * animation first rotate the new content into the old orientation to then be able to * animate to the new orientation * - * <li> The Background color frame: <p> - * To have the animation seem more seamless, we add a color transitioning background behind the - * exiting and entering layouts. We compute the brightness of the start and end - * layouts and transition from the two brightness values as grayscale underneath the animation + * <li> The exiting Blackframe: <p> + * Because the change of orientation might change the width and height of the content (i.e + * when rotating from portrait to landscape) we "crop" the new content using black frames + * around the screenshot so the new content does not go beyond the screenshot's bounds * * <li> The entering Blackframe: <p> * The enter Blackframe is similar to the exit Blackframe but is only used when a custom @@ -89,6 +81,8 @@ class ScreenRotationAnimation { */ private static final int SCREEN_FREEZE_LAYER_BASE = WINDOW_FREEZE_LAYER + TYPE_LAYER_MULTIPLIER; private static final int SCREEN_FREEZE_LAYER_ENTER = SCREEN_FREEZE_LAYER_BASE; + private static final int SCREEN_FREEZE_LAYER_SCREENSHOT = SCREEN_FREEZE_LAYER_BASE + 1; + private static final int SCREEN_FREEZE_LAYER_EXIT = SCREEN_FREEZE_LAYER_BASE + 2; private final Context mContext; private final DisplayContent mDisplayContent; @@ -96,18 +90,16 @@ class ScreenRotationAnimation { private final Transformation mRotateExitTransformation = new Transformation(); private final Transformation mRotateEnterTransformation = new Transformation(); // Complete transformations being applied. + private final Transformation mExitTransformation = new Transformation(); private final Transformation mEnterTransformation = new Transformation(); + private final Matrix mFrameInitialMatrix = new Matrix(); private final Matrix mSnapshotInitialMatrix = new Matrix(); + private final Matrix mSnapshotFinalMatrix = new Matrix(); + private final Matrix mExitFrameFinalMatrix = new Matrix(); private final WindowManagerService mService; - /** Only used for custom animations and not screen rotation. */ private SurfaceControl mEnterBlackFrameLayer; - /** This layer contains the actual screenshot that is to be faded out. */ - private SurfaceControl mScreenshotLayer; - /** - * Only used for screen rotation and not custom animations. Layered behind all other layers - * to avoid showing any "empty" spots - */ - private SurfaceControl mBackColorSurface; + private SurfaceControl mRotationLayer; + private SurfaceControl mSurfaceControl; private BlackFrame mEnteringBlackFrame; private int mWidth, mHeight; @@ -128,11 +120,8 @@ class ScreenRotationAnimation { private boolean mFinishAnimReady; private long mFinishAnimStartTime; private boolean mForceDefaultOrientation; + private BlackFrame mExitingBlackFrame; private SurfaceRotationAnimationController mSurfaceRotationAnimationController; - /** Intensity of light/whiteness of the layout before rotation occurs. */ - private float mStartLuma; - /** Intensity of light/whiteness of the layout after rotation occurs. */ - private float mEndLuma; public ScreenRotationAnimation(Context context, DisplayContent displayContent, boolean fixedToUserRotation, boolean isSecure, WindowManagerService service) { @@ -173,15 +162,9 @@ class ScreenRotationAnimation { final SurfaceControl.Transaction t = mService.mTransactionFactory.get(); try { - mBackColorSurface = displayContent.makeChildSurface(null) - .setName("BackColorSurface") - .setColorLayer() - .build(); - - mScreenshotLayer = displayContent.makeOverlay() + mRotationLayer = displayContent.makeOverlay() .setName("RotationLayer") - .setBufferSize(mWidth, mHeight) - .setSecure(isSecure) + .setContainerLayer() .build(); mEnterBlackFrameLayer = displayContent.makeOverlay() @@ -189,21 +172,26 @@ class ScreenRotationAnimation { .setContainerLayer() .build(); + mSurfaceControl = mService.makeSurfaceBuilder(null) + .setName("ScreenshotSurface") + .setParent(mRotationLayer) + .setBufferSize(mWidth, mHeight) + .setSecure(isSecure) + .build(); + // In case display bounds change, screenshot buffer and surface may mismatch so set a // scaling mode. SurfaceControl.Transaction t2 = mService.mTransactionFactory.get(); - t2.setOverrideScalingMode(mScreenshotLayer, Surface.SCALING_MODE_SCALE_TO_WINDOW); + t2.setOverrideScalingMode(mSurfaceControl, Surface.SCALING_MODE_SCALE_TO_WINDOW); t2.apply(true /* sync */); // Capture a screenshot into the surface we just created. final int displayId = display.getDisplayId(); final Surface surface = mService.mSurfaceFactory.get(); - surface.copyFrom(mScreenshotLayer); + surface.copyFrom(mSurfaceControl); SurfaceControl.ScreenshotGraphicBuffer gb = mService.mDisplayManagerInternal.screenshot(displayId); if (gb != null) { - mStartLuma = RotationAnimationUtils.getAvgBorderLuma(gb.getGraphicBuffer(), - gb.getColorSpace()); try { surface.attachAndQueueBufferWithColorSpace(gb.getGraphicBuffer(), gb.getColorSpace()); @@ -214,15 +202,13 @@ class ScreenRotationAnimation { // screenshot surface we display it in also has FLAG_SECURE so that // the user can not screenshot secure layers via the screenshot surface. if (gb.containsSecureLayers()) { - t.setSecure(mScreenshotLayer, true); + t.setSecure(mSurfaceControl, true); } - t.setLayer(mScreenshotLayer, SCREEN_FREEZE_LAYER_BASE); - t.reparent(mBackColorSurface, displayContent.getSurfaceControl()); - t.setLayer(mBackColorSurface, -1); - t.setColor(mBackColorSurface, new float[]{mStartLuma, mStartLuma, mStartLuma}); - t.setAlpha(mBackColorSurface, 1); - t.show(mScreenshotLayer); - t.show(mBackColorSurface); + t.setLayer(mRotationLayer, SCREEN_FREEZE_LAYER_BASE); + t.setLayer(mSurfaceControl, SCREEN_FREEZE_LAYER_SCREENSHOT); + t.setAlpha(mSurfaceControl, 0); + t.show(mRotationLayer); + t.show(mSurfaceControl); } else { Slog.w(TAG, "Unable to take screenshot of display " + displayId); } @@ -232,11 +218,32 @@ class ScreenRotationAnimation { } ProtoLog.i(WM_SHOW_SURFACE_ALLOC, - " FREEZE %s: CREATE", mScreenshotLayer); + " FREEZE %s: CREATE", mSurfaceControl); setRotation(t, originalRotation); t.apply(); } + private static void createRotationMatrix(int rotation, int width, int height, + Matrix outMatrix) { + switch (rotation) { + case Surface.ROTATION_0: + outMatrix.reset(); + break; + case Surface.ROTATION_90: + outMatrix.setRotate(90, 0, 0); + outMatrix.postTranslate(height, 0); + break; + case Surface.ROTATION_180: + outMatrix.setRotate(180, 0, 0); + outMatrix.postTranslate(width, height); + break; + case Surface.ROTATION_270: + outMatrix.setRotate(270, 0, 0); + outMatrix.postTranslate(0, width); + break; + } + } + public void dumpDebug(ProtoOutputStream proto, long fieldId) { final long token = proto.start(fieldId); proto.write(STARTED, mStarted); @@ -245,11 +252,11 @@ class ScreenRotationAnimation { } boolean hasScreenshot() { - return mScreenshotLayer != null; + return mSurfaceControl != null; } private void setRotationTransform(SurfaceControl.Transaction t, Matrix matrix) { - if (mScreenshotLayer == null) { + if (mRotationLayer == null) { return; } matrix.getValues(mTmpFloats); @@ -260,19 +267,24 @@ class ScreenRotationAnimation { x -= mCurrentDisplayRect.left; y -= mCurrentDisplayRect.top; } - t.setPosition(mScreenshotLayer, x, y); - t.setMatrix(mScreenshotLayer, + t.setPosition(mRotationLayer, x, y); + t.setMatrix(mRotationLayer, mTmpFloats[Matrix.MSCALE_X], mTmpFloats[Matrix.MSKEW_Y], mTmpFloats[Matrix.MSKEW_X], mTmpFloats[Matrix.MSCALE_Y]); - t.setAlpha(mScreenshotLayer, (float) 1.0); - t.show(mScreenshotLayer); + t.setAlpha(mSurfaceControl, (float) 1.0); + t.setAlpha(mRotationLayer, (float) 1.0); + t.show(mRotationLayer); } public void printTo(String prefix, PrintWriter pw) { - pw.print(prefix); pw.print("mSurface="); pw.print(mScreenshotLayer); + pw.print(prefix); pw.print("mSurface="); pw.print(mSurfaceControl); pw.print(" mWidth="); pw.print(mWidth); pw.print(" mHeight="); pw.println(mHeight); + pw.print(prefix); pw.print("mExitingBlackFrame="); pw.println(mExitingBlackFrame); + if (mExitingBlackFrame != null) { + mExitingBlackFrame.printTo(prefix + " ", pw); + } pw.print(prefix); pw.print("mEnteringBlackFrame="); pw.println(mEnteringBlackFrame); @@ -291,10 +303,20 @@ class ScreenRotationAnimation { pw.print(" "); mRotateExitTransformation.printShortString(pw); pw.println(); pw.print(prefix); pw.print("mRotateEnterAnimation="); pw.print(mRotateEnterAnimation); pw.print(" "); mRotateEnterTransformation.printShortString(pw); pw.println(); + pw.print(prefix); pw.print("mExitTransformation="); + mExitTransformation.printShortString(pw); pw.println(); pw.print(prefix); pw.print("mEnterTransformation="); mEnterTransformation.printShortString(pw); pw.println(); + pw.print(prefix); pw.print("mFrameInitialMatrix="); + mFrameInitialMatrix.printShortString(pw); + pw.println(); pw.print(prefix); pw.print("mSnapshotInitialMatrix="); - mSnapshotInitialMatrix.printShortString(pw);pw.println(); + mSnapshotInitialMatrix.printShortString(pw); + pw.print(" mSnapshotFinalMatrix="); mSnapshotFinalMatrix.printShortString(pw); + pw.println(); + pw.print(prefix); pw.print("mExitFrameFinalMatrix="); + mExitFrameFinalMatrix.printShortString(pw); + pw.println(); pw.print(prefix); pw.print("mForceDefaultOrientation="); pw.print(mForceDefaultOrientation); if (mForceDefaultOrientation) { pw.print(" mOriginalDisplayRect="); pw.print(mOriginalDisplayRect.toShortString()); @@ -309,7 +331,7 @@ class ScreenRotationAnimation { // to the snapshot to make it stay in the same original position // with the current screen rotation. int delta = DisplayContent.deltaRotation(rotation, Surface.ROTATION_0); - RotationAnimationUtils.createRotationMatrix(delta, mWidth, mHeight, mSnapshotInitialMatrix); + createRotationMatrix(delta, mWidth, mHeight, mSnapshotInitialMatrix); setRotationTransform(t, mSnapshotInitialMatrix); } @@ -319,7 +341,7 @@ class ScreenRotationAnimation { */ private boolean startAnimation(SurfaceControl.Transaction t, long maxAnimationDuration, float animationScale, int finalWidth, int finalHeight, int exitAnim, int enterAnim) { - if (mScreenshotLayer == null) { + if (mSurfaceControl == null) { // Can't do animation. return false; } @@ -332,58 +354,89 @@ class ScreenRotationAnimation { // Figure out how the screen has moved from the original rotation. int delta = DisplayContent.deltaRotation(mCurRotation, mOriginalRotation); + mRotateAlphaAnimation = AnimationUtils.loadAnimation(mContext, + com.android.internal.R.anim.screen_rotate_alpha); final boolean customAnim; if (exitAnim != 0 && enterAnim != 0) { customAnim = true; mRotateExitAnimation = AnimationUtils.loadAnimation(mContext, exitAnim); mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext, enterAnim); - mRotateAlphaAnimation = AnimationUtils.loadAnimation(mContext, - R.anim.screen_rotate_alpha); } else { customAnim = false; - switch (delta) { /* Counter-Clockwise Rotations */ + switch (delta) { case Surface.ROTATION_0: mRotateExitAnimation = AnimationUtils.loadAnimation(mContext, - R.anim.screen_rotate_0_exit); + com.android.internal.R.anim.screen_rotate_0_exit); mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext, - R.anim.screen_rotate_0_enter); + com.android.internal.R.anim.screen_rotate_0_enter); break; case Surface.ROTATION_90: mRotateExitAnimation = AnimationUtils.loadAnimation(mContext, - R.anim.screen_rotate_plus_90_exit); + com.android.internal.R.anim.screen_rotate_plus_90_exit); mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext, - R.anim.screen_rotate_plus_90_enter); + com.android.internal.R.anim.screen_rotate_plus_90_enter); break; case Surface.ROTATION_180: mRotateExitAnimation = AnimationUtils.loadAnimation(mContext, - R.anim.screen_rotate_180_exit); + com.android.internal.R.anim.screen_rotate_180_exit); mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext, - R.anim.screen_rotate_180_enter); + com.android.internal.R.anim.screen_rotate_180_enter); break; case Surface.ROTATION_270: mRotateExitAnimation = AnimationUtils.loadAnimation(mContext, - R.anim.screen_rotate_minus_90_exit); + com.android.internal.R.anim.screen_rotate_minus_90_exit); mRotateEnterAnimation = AnimationUtils.loadAnimation(mContext, - R.anim.screen_rotate_minus_90_enter); + com.android.internal.R.anim.screen_rotate_minus_90_enter); break; } } + // Initialize the animations. This is a hack, redefining what "parent" + // 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. + mRotateEnterAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight); mRotateExitAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight); + mAnimRunning = false; + mFinishAnimReady = false; + mFinishAnimStartTime = -1; + mRotateExitAnimation.restrictDuration(maxAnimationDuration); mRotateExitAnimation.scaleCurrentDuration(animationScale); - mRotateEnterAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight); mRotateEnterAnimation.restrictDuration(maxAnimationDuration); mRotateEnterAnimation.scaleCurrentDuration(animationScale); + mRotateAlphaAnimation.restrictDuration(maxAnimationDuration); + mRotateAlphaAnimation.scaleCurrentDuration(animationScale); - mAnimRunning = false; - mFinishAnimReady = false; - mFinishAnimStartTime = -1; - - if (customAnim) { - mRotateAlphaAnimation.restrictDuration(maxAnimationDuration); - mRotateAlphaAnimation.scaleCurrentDuration(animationScale); + if (!customAnim && mExitingBlackFrame == null) { + try { + // Compute the transformation matrix that must be applied + // the the black frame to make it stay in the initial position + // before the new screen rotation. This is different than the + // snapshot transformation because the snapshot is always based + // of the native orientation of the screen, not the orientation + // we were last in. + createRotationMatrix(delta, mOriginalWidth, mOriginalHeight, mFrameInitialMatrix); + + final Rect outer; + final Rect inner; + if (mForceDefaultOrientation) { + // Going from a smaller Display to a larger Display, add curtains to sides + // or top and bottom. Going from a larger to smaller display will result in + // no BlackSurfaces being constructed. + outer = mCurrentDisplayRect; + inner = mOriginalDisplayRect; + } else { + outer = new Rect(-mWidth, -mHeight, mWidth * 2, mHeight * 2); + inner = new Rect(0, 0, mWidth, mHeight); + } + mExitingBlackFrame = new BlackFrame(mService.mTransactionFactory, t, outer, inner, + SCREEN_FREEZE_LAYER_EXIT, mDisplayContent, mForceDefaultOrientation, + mRotationLayer); + } catch (OutOfResourcesException e) { + Slog.w(TAG, "Unable to allocate black surface", e); + } } if (customAnim && mEnteringBlackFrame == null) { @@ -398,12 +451,7 @@ class ScreenRotationAnimation { } } - if (customAnim) { - mSurfaceRotationAnimationController.startCustomAnimation(); - } else { - mSurfaceRotationAnimationController.startScreenRotationAnimation(); - } - + mSurfaceRotationAnimationController.startAnimation(); return true; } @@ -412,13 +460,11 @@ class ScreenRotationAnimation { */ public boolean dismiss(SurfaceControl.Transaction t, long maxAnimationDuration, float animationScale, int finalWidth, int finalHeight, int exitAnim, int enterAnim) { - if (mScreenshotLayer == null) { + if (mSurfaceControl == null) { // Can't do animation. return false; } if (!mStarted) { - mEndLuma = RotationAnimationUtils.getLumaOfSurfaceControl(mDisplayContent.getDisplay(), - mDisplayContent.getWindowingLayer()); startAnimation(t, maxAnimationDuration, animationScale, finalWidth, finalHeight, exitAnim, enterAnim); } @@ -434,28 +480,28 @@ class ScreenRotationAnimation { mSurfaceRotationAnimationController.cancel(); mSurfaceRotationAnimationController = null; } - - if (mScreenshotLayer != null) { - ProtoLog.i(WM_SHOW_SURFACE_ALLOC, " FREEZE %s: DESTROY", mScreenshotLayer); + if (mSurfaceControl != null) { + ProtoLog.i(WM_SHOW_SURFACE_ALLOC, " FREEZE %s: DESTROY", mSurfaceControl); + mSurfaceControl = null; SurfaceControl.Transaction t = mService.mTransactionFactory.get(); - if (mScreenshotLayer.isValid()) { - t.remove(mScreenshotLayer); + if (mRotationLayer != null) { + if (mRotationLayer.isValid()) { + t.remove(mRotationLayer); + } + mRotationLayer = null; } - mScreenshotLayer = null; - if (mEnterBlackFrameLayer != null) { if (mEnterBlackFrameLayer.isValid()) { t.remove(mEnterBlackFrameLayer); } mEnterBlackFrameLayer = null; } - if (mBackColorSurface != null) { - t.remove(mBackColorSurface); - mBackColorSurface = null; - } t.apply(); } - + if (mExitingBlackFrame != null) { + mExitingBlackFrame.kill(); + mExitingBlackFrame = null; + } if (mEnteringBlackFrame != null) { mEnteringBlackFrame.kill(); mEnteringBlackFrame = null; @@ -491,28 +537,18 @@ class ScreenRotationAnimation { * Utility class that runs a {@link ScreenRotationAnimation} on the {@link * SurfaceAnimationRunner}. * <p> - * The rotation animation supports both screen rotation and custom animations - * - * For custom animations: - * <ul> - * <li> - * The screenshot layer which has an added animation of it's alpha channel - * ("screen_rotate_alpha") and that will be applied along with the custom animation. - * </li> - * <li> A device layer that is animated with the provided custom animation </li> - * </ul> - * - * For screen rotation: + * The rotation animation is divided into the following hierarchy: * <ul> - * <li> A rotation layer that is both rotated and faded out during a single animation </li> - * <li> A device layer that is both rotated and faded in during a single animation </li> - * <li> A background color layer that transitions colors behind the first two layers </li> - * </ul> - * + * <li> A first rotation layer, containing the blackframes. This layer is animated by the + * "screen_rotate_X_exit" that applies a scale and rotate and where X is value of the rotation. + * <ul> + * <li> A child layer containing the screenshot on which is added an animation of it's + * alpha channel ("screen_rotate_alpha") and that will rotate with his parent layer.</li> + * </ul> + * <li> A second rotation layer used when custom animations are passed in * {@link ScreenRotationAnimation#startAnimation( * SurfaceControl.Transaction, long, float, int, int, int, int)}. * </ul> - * * <p> * Thus an {@link LocalAnimationAdapter.AnimationSpec} is created for each of * this three {@link SurfaceControl}s which then delegates the animation to the @@ -520,35 +556,22 @@ class ScreenRotationAnimation { */ class SurfaceRotationAnimationController { private SurfaceAnimator mDisplayAnimator; + private SurfaceAnimator mEnterBlackFrameAnimator; private SurfaceAnimator mScreenshotRotationAnimator; private SurfaceAnimator mRotateScreenAnimator; - private SurfaceAnimator mEnterBlackFrameAnimator; - - void startCustomAnimation() { - try { - mService.mSurfaceAnimationRunner.deferStartingAnimations(); - mRotateScreenAnimator = startScreenshotAlphaAnimation(); - mDisplayAnimator = startDisplayRotation(); - if (mEnteringBlackFrame != null) { - mEnterBlackFrameAnimator = startEnterBlackFrameAnimation(); - } - } finally { - mService.mSurfaceAnimationRunner.continueStartingAnimations(); - } - } /** * Start the rotation animation of the display and the screenshot on the * {@link SurfaceAnimationRunner}. */ - void startScreenRotationAnimation() { - try { - mService.mSurfaceAnimationRunner.deferStartingAnimations(); - mDisplayAnimator = startDisplayRotation(); + void startAnimation() { + mRotateScreenAnimator = startScreenshotAlphaAnimation(); + mDisplayAnimator = startDisplayRotation(); + if (mExitingBlackFrame != null) { mScreenshotRotationAnimator = startScreenshotRotationAnimation(); - startColorAnimation(); - } finally { - mService.mSurfaceAnimationRunner.continueStartingAnimations(); + } + if (mEnteringBlackFrame != null) { + mEnterBlackFrameAnimator = startEnterBlackFrameAnimation(); } } @@ -573,8 +596,8 @@ class ScreenRotationAnimation { private SurfaceAnimator startScreenshotAlphaAnimation() { return startAnimation(initializeBuilder() - .setSurfaceControl(mScreenshotLayer) - .setAnimationLeashParent(mDisplayContent.getOverlayLayer()) + .setSurfaceControl(mSurfaceControl) + .setAnimationLeashParent(mRotationLayer) .setWidth(mWidth) .setHeight(mHeight) .build(), @@ -593,67 +616,13 @@ class ScreenRotationAnimation { private SurfaceAnimator startScreenshotRotationAnimation() { return startAnimation(initializeBuilder() - .setSurfaceControl(mScreenshotLayer) + .setSurfaceControl(mRotationLayer) .setAnimationLeashParent(mDisplayContent.getOverlayLayer()) .build(), createWindowAnimationSpec(mRotateExitAnimation), this::onAnimationEnd); } - - /** - * Applies the color change from {@link #mStartLuma} to {@link #mEndLuma} as a - * grayscale color - */ - private void startColorAnimation() { - int colorTransitionMs = mContext.getResources().getInteger( - R.integer.config_screen_rotation_color_transition); - final SurfaceAnimationRunner runner = mService.mSurfaceAnimationRunner; - final float[] rgbTmpFloat = new float[3]; - final int startColor = Color.rgb(mStartLuma, mStartLuma, mStartLuma); - final int endColor = Color.rgb(mEndLuma, mEndLuma, mEndLuma); - final long duration = colorTransitionMs * (long) mService.getCurrentAnimatorScale(); - final ArgbEvaluator va = ArgbEvaluator.getInstance(); - runner.startAnimation( - new LocalAnimationAdapter.AnimationSpec() { - @Override - public long getDuration() { - return duration; - } - - @Override - public void apply(SurfaceControl.Transaction t, SurfaceControl leash, - long currentPlayTime) { - float fraction = (float)currentPlayTime / (float)getDuration(); - int color = (Integer) va.evaluate(fraction, startColor, endColor); - Color middleColor = Color.valueOf(color); - rgbTmpFloat[0] = middleColor.red(); - rgbTmpFloat[1] = middleColor.green(); - rgbTmpFloat[2] = middleColor.blue(); - if (leash.isValid()) { - t.setColor(leash, rgbTmpFloat); - } - } - - @Override - public void dump(PrintWriter pw, String prefix) { - pw.println(prefix + "startLuma=" + mStartLuma - + " endLuma=" + mEndLuma - + " durationMs=" + colorTransitionMs); - } - - @Override - public void dumpDebugInner(ProtoOutputStream proto) { - final long token = proto.start(ROTATE); - proto.write(START_LUMA, mStartLuma); - proto.write(END_LUMA, mEndLuma); - proto.write(DURATION_MS, colorTransitionMs); - proto.end(token); - } - }, - mBackColorSurface, mDisplayContent.getPendingTransaction(), null); - } - private WindowAnimationSpec createWindowAnimationSpec(Animation mAnimation) { return new WindowAnimationSpec(mAnimation, new Point(0, 0) /* position */, false /* canSkipFirstFrame */, 0 /* WindowCornerRadius */); @@ -677,6 +646,7 @@ class ScreenRotationAnimation { LocalAnimationAdapter localAnimationAdapter = new LocalAnimationAdapter( animationSpec, mService.mSurfaceAnimationRunner); + animator.startAnimation(mDisplayContent.getPendingTransaction(), localAnimationAdapter, false); return animator; @@ -722,6 +692,7 @@ class ScreenRotationAnimation { if (mEnterBlackFrameAnimator != null) { mEnterBlackFrameAnimator.cancelAnimation(); } + if (mScreenshotRotationAnimator != null) { mScreenshotRotationAnimator.cancelAnimation(); } diff --git a/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java b/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java index b3fc1552eb25..bbd986f30a6b 100644 --- a/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java +++ b/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java @@ -75,10 +75,6 @@ class SurfaceAnimationRunner { @GuardedBy("mLock") private boolean mAnimationStartDeferred; - /** - * There should only ever be one instance of this class. Usual spot for it is with - * {@link WindowManagerService} - */ SurfaceAnimationRunner(Supplier<Transaction> transactionFactory, PowerManagerInternal powerManagerInternal) { this(null /* callbackProvider */, null /* animatorFactory */, diff --git a/services/core/java/com/android/server/wm/utils/RotationAnimationUtils.java b/services/core/java/com/android/server/wm/utils/RotationAnimationUtils.java deleted file mode 100644 index 94f66768d5ef..000000000000 --- a/services/core/java/com/android/server/wm/utils/RotationAnimationUtils.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (C) 2019 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. - */ - -package com.android.server.wm.utils; - -import android.graphics.Bitmap; -import android.graphics.ColorSpace; -import android.graphics.GraphicBuffer; -import android.graphics.Matrix; -import android.graphics.Point; -import android.graphics.Rect; -import android.view.Display; -import android.view.Surface; -import android.view.SurfaceControl; - - -/** Helper functions for the {@link com.android.server.wm.ScreenRotationAnimation} class*/ -public class RotationAnimationUtils { - - /** - * Converts the provided {@link GraphicBuffer} and converts it to a bitmap to then sample the - * luminance at the borders of the bitmap - * @return the average luminance of all the pixels at the borders of the bitmap - */ - public static float getAvgBorderLuma(GraphicBuffer graphicBuffer, ColorSpace colorSpace) { - Bitmap hwBitmap = Bitmap.wrapHardwareBuffer(graphicBuffer, colorSpace); - if (hwBitmap == null) { - return 0; - } - - Bitmap swaBitmap = hwBitmap.copy(Bitmap.Config.ARGB_8888, false); - float totalLuma = 0; - int height = swaBitmap.getHeight(); - int width = swaBitmap.getWidth(); - int i; - for (i = 0; i < width; i++) { - totalLuma += swaBitmap.getColor(i, 0).luminance(); - totalLuma += swaBitmap.getColor(i, height - 1).luminance(); - } - for (i = 0; i < height; i++) { - totalLuma += swaBitmap.getColor(0, i).luminance(); - totalLuma += swaBitmap.getColor(width - 1, i).luminance(); - } - return totalLuma / (2 * width + 2 * height); - } - - /** - * Gets the average border luma by taking a screenshot of the {@param surfaceControl}. - * @see #getAvgBorderLuma(GraphicBuffer, ColorSpace) - */ - public static float getLumaOfSurfaceControl(Display display, SurfaceControl surfaceControl) { - if (surfaceControl == null) { - return 0; - } - - Point size = new Point(); - display.getSize(size); - Rect crop = new Rect(0, 0, size.x, size.y); - SurfaceControl.ScreenshotGraphicBuffer buffer = - SurfaceControl.captureLayers(surfaceControl, crop, 1); - return RotationAnimationUtils.getAvgBorderLuma(buffer.getGraphicBuffer(), - buffer.getColorSpace()); - } - - public static void createRotationMatrix(int rotation, int width, int height, Matrix outMatrix) { - switch (rotation) { - case Surface.ROTATION_0: - outMatrix.reset(); - break; - case Surface.ROTATION_90: - outMatrix.setRotate(90, 0, 0); - outMatrix.postTranslate(height, 0); - break; - case Surface.ROTATION_180: - outMatrix.setRotate(180, 0, 0); - outMatrix.postTranslate(width, height); - break; - case Surface.ROTATION_270: - outMatrix.setRotate(270, 0, 0); - outMatrix.postTranslate(0, width); - break; - } - } -} diff --git a/services/tests/wmtests/src/com/android/server/wm/utils/RotationAnimationUtilsTest.java b/services/tests/wmtests/src/com/android/server/wm/utils/RotationAnimationUtilsTest.java deleted file mode 100644 index 9cda08458640..000000000000 --- a/services/tests/wmtests/src/com/android/server/wm/utils/RotationAnimationUtilsTest.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (C) 2019 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. - */ - -package com.android.server.wm.utils; - -import static android.graphics.Bitmap.Config.ARGB_8888; - -import static org.junit.Assert.assertEquals; - -import android.graphics.Bitmap; -import android.graphics.Color; -import android.graphics.ColorSpace; -import android.graphics.GraphicBuffer; -import android.graphics.Matrix; -import android.graphics.PointF; -import android.view.Surface; - -import org.junit.Before; -import org.junit.Test; - -public class RotationAnimationUtilsTest { - - private static final int BITMAP_HEIGHT = 100; - private static final int BITMAP_WIDTH = 100; - private static final int POINT_WIDTH = 1000; - private static final int POINT_HEIGHT = 2000; - - private ColorSpace mColorSpace = ColorSpace.get(ColorSpace.Named.DISPLAY_P3); - private Matrix mMatrix; - - @Before - public void setup() { - mMatrix = new Matrix(); - } - - @Test - public void blackLuma() { - Bitmap swBitmap = createBitmap(0); - GraphicBuffer gb = swBitmapToGraphicsBuffer(swBitmap); - float borderLuma = RotationAnimationUtils.getAvgBorderLuma(gb, mColorSpace); - assertEquals(0, borderLuma, 0); - } - - @Test - public void whiteLuma() { - Bitmap swBitmap = createBitmap(1); - GraphicBuffer gb = swBitmapToGraphicsBuffer(swBitmap); - float borderLuma = RotationAnimationUtils.getAvgBorderLuma(gb, mColorSpace); - assertEquals(1, borderLuma, 0); - } - - @Test - public void whiteImageBlackBorderLuma() { - Bitmap swBitmap = createBitmap(1); - setBorderLuma(swBitmap, 0); - GraphicBuffer gb = swBitmapToGraphicsBuffer(swBitmap); - float borderLuma = RotationAnimationUtils.getAvgBorderLuma(gb, mColorSpace); - assertEquals(0, borderLuma, 0); - } - - @Test - public void blackImageWhiteBorderLuma() { - Bitmap swBitmap = createBitmap(0); - setBorderLuma(swBitmap, 1); - GraphicBuffer gb = swBitmapToGraphicsBuffer(swBitmap); - float borderLuma = RotationAnimationUtils.getAvgBorderLuma(gb, mColorSpace); - assertEquals(1, borderLuma, 0); - } - - @Test - public void rotate_0_bottomRight() { - RotationAnimationUtils.createRotationMatrix(Surface.ROTATION_0, - POINT_WIDTH, POINT_HEIGHT, mMatrix); - PointF newPoints = checkMappedPoints(POINT_WIDTH, POINT_HEIGHT); - assertEquals(POINT_WIDTH, newPoints.x, 0); - assertEquals(POINT_HEIGHT, newPoints.y, 0); - } - - @Test - public void rotate_90_bottomRight() { - RotationAnimationUtils.createRotationMatrix(Surface.ROTATION_90, - POINT_WIDTH, POINT_HEIGHT, mMatrix); - PointF newPoints = checkMappedPoints(POINT_WIDTH, POINT_HEIGHT); - assertEquals(0, newPoints.x, 0); - assertEquals(POINT_WIDTH, newPoints.y, 0); - } - - @Test - public void rotate_180_bottomRight() { - RotationAnimationUtils.createRotationMatrix(Surface.ROTATION_180, - POINT_WIDTH, POINT_HEIGHT, mMatrix); - PointF newPoints = checkMappedPoints(POINT_WIDTH, POINT_HEIGHT); - assertEquals(0, newPoints.x, 0); - assertEquals(0, newPoints.y, 0); - } - - @Test - public void rotate_270_bottomRight() { - RotationAnimationUtils.createRotationMatrix(Surface.ROTATION_270, - POINT_WIDTH, POINT_HEIGHT, mMatrix); - PointF newPoints = checkMappedPoints(POINT_WIDTH, POINT_HEIGHT); - assertEquals(POINT_HEIGHT, newPoints.x, 0); - assertEquals(0, newPoints.y, 0); - } - - private PointF checkMappedPoints(int x, int y) { - final float[] fs = new float[] {x, y}; - mMatrix.mapPoints(fs); - return new PointF(fs[0], fs[1]); - } - - private Bitmap createBitmap(float luma) { - Bitmap bitmap = Bitmap.createBitmap(BITMAP_WIDTH, BITMAP_HEIGHT, ARGB_8888); - for (int i = 0; i < BITMAP_WIDTH; i++) { - for (int j = 0; j < BITMAP_HEIGHT; j++) { - bitmap.setPixel(i, j, Color.argb(1, luma, luma, luma)); - } - } - return bitmap; - } - - private GraphicBuffer swBitmapToGraphicsBuffer(Bitmap swBitmap) { - Bitmap hwBitmap = swBitmap.copy(Bitmap.Config.HARDWARE, false); - return hwBitmap.createGraphicBufferHandle(); - } - - private void setBorderLuma(Bitmap swBitmap, float luma) { - int i; - int width = swBitmap.getWidth(); - int height = swBitmap.getHeight(); - for (i = 0; i < width; i++) { - swBitmap.setPixel(i, 0, Color.argb(1, luma, luma, luma)); - swBitmap.setPixel(i, height - 1, Color.argb(1, luma, luma, luma)); - } - for (i = 0; i < height; i++) { - swBitmap.setPixel(0, i, Color.argb(1, luma, luma, luma)); - swBitmap.setPixel(width - 1, i, Color.argb(1, luma, luma, luma)); - } - } -} |