summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/WindowManager/Shell/res/values/config.xml4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java60
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java51
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java165
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java220
-rw-r--r--native/android/surface_control.cpp4
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/NavigationEdgeBackPlugin.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/ScreenDecorations.java34
-rw-r--r--packages/SystemUI/src/com/android/systemui/decor/RoundedCornerResDelegate.kt17
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationBarEdgePanel.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooterUtils.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java56
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/decor/RoundedCornerResDelegateTest.kt12
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java18
-rw-r--r--services/companion/java/com/android/server/companion/presence/BleCompanionDeviceScanner.java36
-rw-r--r--services/core/java/com/android/server/display/LocalDisplayAdapter.java14
-rw-r--r--services/core/java/com/android/server/wm/AppTransitionController.java5
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java39
22 files changed, 499 insertions, 276 deletions
diff --git a/libs/WindowManager/Shell/res/values/config.xml b/libs/WindowManager/Shell/res/values/config.xml
index f03b7f66cdc8..30c3d50ed8ad 100644
--- a/libs/WindowManager/Shell/res/values/config.xml
+++ b/libs/WindowManager/Shell/res/values/config.xml
@@ -19,6 +19,10 @@
by the resources of the app using the Shell library. -->
<bool name="config_enableShellMainThread">false</bool>
+ <!-- Determines whether to register the shell task organizer on init.
+ TODO(b/238217847): This config is temporary until we refactor the base WMComponent. -->
+ <bool name="config_registerShellTaskOrganizerOnInit">true</bool>
+
<!-- Animation duration for PIP when entering. -->
<integer name="config_pipEnterAnimationDuration">425</integer>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java
index 1c0e6f726fbf..756d80204833 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java
@@ -20,6 +20,9 @@ import static android.view.WindowManager.TRANSIT_CHANGE;
import static android.view.WindowManagerPolicyConstants.TYPE_LAYER_OFFSET;
import static android.window.TransitionInfo.FLAG_IS_BEHIND_STARTING_WINDOW;
+import static com.android.wm.shell.transition.TransitionAnimationHelper.addBackgroundToTransition;
+import static com.android.wm.shell.transition.TransitionAnimationHelper.getTransitionBackgroundColorIfSet;
+
import android.animation.Animator;
import android.animation.ValueAnimator;
import android.content.Context;
@@ -42,7 +45,6 @@ import com.android.wm.shell.transition.Transitions;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
-import java.util.function.BiFunction;
/** To run the ActivityEmbedding animations. */
class ActivityEmbeddingAnimationRunner {
@@ -85,7 +87,7 @@ class ActivityEmbeddingAnimationRunner {
@NonNull SurfaceControl.Transaction finishTransaction,
@NonNull Runnable animationFinishCallback) {
final List<ActivityEmbeddingAnimationAdapter> adapters =
- createAnimationAdapters(info, startTransaction);
+ createAnimationAdapters(info, startTransaction, finishTransaction);
long duration = 0;
for (ActivityEmbeddingAnimationAdapter adapter : adapters) {
duration = Math.max(duration, adapter.getDurationHint());
@@ -129,7 +131,8 @@ class ActivityEmbeddingAnimationRunner {
*/
@NonNull
private List<ActivityEmbeddingAnimationAdapter> createAnimationAdapters(
- @NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction startTransaction) {
+ @NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction startTransaction,
+ @NonNull SurfaceControl.Transaction finishTransaction) {
boolean isChangeTransition = false;
for (TransitionInfo.Change change : info.getChanges()) {
if (change.hasFlags(FLAG_IS_BEHIND_STARTING_WINDOW)) {
@@ -145,23 +148,25 @@ class ActivityEmbeddingAnimationRunner {
return createChangeAnimationAdapters(info, startTransaction);
}
if (Transitions.isClosingType(info.getType())) {
- return createCloseAnimationAdapters(info);
+ return createCloseAnimationAdapters(info, startTransaction, finishTransaction);
}
- return createOpenAnimationAdapters(info);
+ return createOpenAnimationAdapters(info, startTransaction, finishTransaction);
}
@NonNull
private List<ActivityEmbeddingAnimationAdapter> createOpenAnimationAdapters(
- @NonNull TransitionInfo info) {
- return createOpenCloseAnimationAdapters(info, true /* isOpening */,
- mAnimationSpec::loadOpenAnimation);
+ @NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction startTransaction,
+ @NonNull SurfaceControl.Transaction finishTransaction) {
+ return createOpenCloseAnimationAdapters(info, startTransaction, finishTransaction,
+ true /* isOpening */, mAnimationSpec::loadOpenAnimation);
}
@NonNull
private List<ActivityEmbeddingAnimationAdapter> createCloseAnimationAdapters(
- @NonNull TransitionInfo info) {
- return createOpenCloseAnimationAdapters(info, false /* isOpening */,
- mAnimationSpec::loadCloseAnimation);
+ @NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction startTransaction,
+ @NonNull SurfaceControl.Transaction finishTransaction) {
+ return createOpenCloseAnimationAdapters(info, startTransaction, finishTransaction,
+ false /* isOpening */, mAnimationSpec::loadCloseAnimation);
}
/**
@@ -170,8 +175,9 @@ class ActivityEmbeddingAnimationRunner {
*/
@NonNull
private List<ActivityEmbeddingAnimationAdapter> createOpenCloseAnimationAdapters(
- @NonNull TransitionInfo info, boolean isOpening,
- @NonNull BiFunction<TransitionInfo.Change, Rect, Animation> animationProvider) {
+ @NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction startTransaction,
+ @NonNull SurfaceControl.Transaction finishTransaction, boolean isOpening,
+ @NonNull AnimationProvider animationProvider) {
// We need to know if the change window is only a partial of the whole animation screen.
// If so, we will need to adjust it to make the whole animation screen looks like one.
final List<TransitionInfo.Change> openingChanges = new ArrayList<>();
@@ -194,7 +200,8 @@ class ActivityEmbeddingAnimationRunner {
final List<ActivityEmbeddingAnimationAdapter> adapters = new ArrayList<>();
for (TransitionInfo.Change change : openingChanges) {
final ActivityEmbeddingAnimationAdapter adapter = createOpenCloseAnimationAdapter(
- change, animationProvider, openingWholeScreenBounds);
+ info, change, startTransaction, finishTransaction, animationProvider,
+ openingWholeScreenBounds);
if (isOpening) {
adapter.overrideLayer(offsetLayer++);
}
@@ -202,7 +209,8 @@ class ActivityEmbeddingAnimationRunner {
}
for (TransitionInfo.Change change : closingChanges) {
final ActivityEmbeddingAnimationAdapter adapter = createOpenCloseAnimationAdapter(
- change, animationProvider, closingWholeScreenBounds);
+ info, change, startTransaction, finishTransaction, animationProvider,
+ closingWholeScreenBounds);
if (!isOpening) {
adapter.overrideLayer(offsetLayer++);
}
@@ -213,10 +221,18 @@ class ActivityEmbeddingAnimationRunner {
@NonNull
private ActivityEmbeddingAnimationAdapter createOpenCloseAnimationAdapter(
- @NonNull TransitionInfo.Change change,
- @NonNull BiFunction<TransitionInfo.Change, Rect, Animation> animationProvider,
- @NonNull Rect wholeAnimationBounds) {
- final Animation animation = animationProvider.apply(change, wholeAnimationBounds);
+ @NonNull TransitionInfo info, @NonNull TransitionInfo.Change change,
+ @NonNull SurfaceControl.Transaction startTransaction,
+ @NonNull SurfaceControl.Transaction finishTransaction,
+ @NonNull AnimationProvider animationProvider, @NonNull Rect wholeAnimationBounds) {
+ final Animation animation = animationProvider.get(info, change, wholeAnimationBounds);
+ // We may want to show a background color for open/close transition.
+ final int backgroundColor = getTransitionBackgroundColorIfSet(info, change, animation,
+ 0 /* defaultColor */);
+ if (backgroundColor != 0) {
+ addBackgroundToTransition(info.getRootLeash(), backgroundColor, startTransaction,
+ finishTransaction);
+ }
return new ActivityEmbeddingAnimationAdapter(animation, change, change.getLeash(),
wholeAnimationBounds);
}
@@ -322,4 +338,10 @@ class ActivityEmbeddingAnimationRunner {
return ScreenshotUtils.takeScreenshot(t, screenshotChange.getLeash(),
animationChange.getLeash(), cropBounds, Integer.MAX_VALUE);
}
+
+ /** To provide an {@link Animation} based on the transition infos. */
+ private interface AnimationProvider {
+ Animation get(@NonNull TransitionInfo info, @NonNull TransitionInfo.Change change,
+ @NonNull Rect animationBounds);
+ }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java
index ad0dddf77002..eb6ac7615266 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java
@@ -17,6 +17,9 @@
package com.android.wm.shell.activityembedding;
+import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITION_NONE;
+import static com.android.wm.shell.transition.TransitionAnimationHelper.loadAttributeAnimation;
+
import android.content.Context;
import android.graphics.Point;
import android.graphics.Rect;
@@ -33,7 +36,6 @@ import android.window.TransitionInfo;
import androidx.annotation.NonNull;
-import com.android.internal.R;
import com.android.internal.policy.TransitionAnimation;
import com.android.wm.shell.transition.Transitions;
@@ -175,16 +177,20 @@ class ActivityEmbeddingAnimationSpec {
}
@NonNull
- Animation loadOpenAnimation(@NonNull TransitionInfo.Change change,
- @NonNull Rect wholeAnimationBounds) {
+ Animation loadOpenAnimation(@NonNull TransitionInfo info,
+ @NonNull TransitionInfo.Change change, @NonNull Rect wholeAnimationBounds) {
final boolean isEnter = Transitions.isOpeningType(change.getMode());
final Animation animation;
- // TODO(b/207070762):
- // 1. Implement clearTop version: R.anim.task_fragment_clear_top_close_enter/exit
- // 2. Implement edgeExtension version
- animation = mTransitionAnimation.loadDefaultAnimationRes(isEnter
- ? R.anim.task_fragment_open_enter
- : R.anim.task_fragment_open_exit);
+ // TODO(b/207070762): Implement edgeExtension version
+ if (shouldShowBackdrop(info, change)) {
+ animation = mTransitionAnimation.loadDefaultAnimationRes(isEnter
+ ? com.android.internal.R.anim.task_fragment_clear_top_open_enter
+ : com.android.internal.R.anim.task_fragment_clear_top_open_exit);
+ } else {
+ animation = mTransitionAnimation.loadDefaultAnimationRes(isEnter
+ ? com.android.internal.R.anim.task_fragment_open_enter
+ : com.android.internal.R.anim.task_fragment_open_exit);
+ }
// Use the whole animation bounds instead of the change bounds, so that when multiple change
// targets are opening at the same time, the animation applied to each will be the same.
// Otherwise, we may see gap between the activities that are launching together.
@@ -195,16 +201,20 @@ class ActivityEmbeddingAnimationSpec {
}
@NonNull
- Animation loadCloseAnimation(@NonNull TransitionInfo.Change change,
- @NonNull Rect wholeAnimationBounds) {
+ Animation loadCloseAnimation(@NonNull TransitionInfo info,
+ @NonNull TransitionInfo.Change change, @NonNull Rect wholeAnimationBounds) {
final boolean isEnter = Transitions.isOpeningType(change.getMode());
final Animation animation;
- // TODO(b/207070762):
- // 1. Implement clearTop version: R.anim.task_fragment_clear_top_close_enter/exit
- // 2. Implement edgeExtension version
- animation = mTransitionAnimation.loadDefaultAnimationRes(isEnter
- ? R.anim.task_fragment_close_enter
- : R.anim.task_fragment_close_exit);
+ // TODO(b/207070762): Implement edgeExtension version
+ if (shouldShowBackdrop(info, change)) {
+ animation = mTransitionAnimation.loadDefaultAnimationRes(isEnter
+ ? com.android.internal.R.anim.task_fragment_clear_top_close_enter
+ : com.android.internal.R.anim.task_fragment_clear_top_close_exit);
+ } else {
+ animation = mTransitionAnimation.loadDefaultAnimationRes(isEnter
+ ? com.android.internal.R.anim.task_fragment_close_enter
+ : com.android.internal.R.anim.task_fragment_close_exit);
+ }
// Use the whole animation bounds instead of the change bounds, so that when multiple change
// targets are closing at the same time, the animation applied to each will be the same.
// Otherwise, we may see gap between the activities that are finishing together.
@@ -213,4 +223,11 @@ class ActivityEmbeddingAnimationSpec {
animation.scaleCurrentDuration(mTransitionAnimationScaleSetting);
return animation;
}
+
+ private boolean shouldShowBackdrop(@NonNull TransitionInfo info,
+ @NonNull TransitionInfo.Change change) {
+ final Animation a = loadAttributeAnimation(info, change, WALLPAPER_TRANSITION_NONE,
+ mTransitionAnimation);
+ return a != null && a.getShowBackdrop();
+ }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
index 80cdd1f79cb5..c25bbbf06dda 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
@@ -29,6 +29,7 @@ import android.view.WindowManager;
import com.android.internal.logging.UiEventLogger;
import com.android.launcher3.icons.IconProvider;
import com.android.wm.shell.ProtoLogController;
+import com.android.wm.shell.R;
import com.android.wm.shell.RootDisplayAreaOrganizer;
import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
import com.android.wm.shell.ShellTaskOrganizer;
@@ -173,6 +174,7 @@ public abstract class WMShellBaseModule {
@WMSingleton
@Provides
static ShellTaskOrganizer provideShellTaskOrganizer(
+ Context context,
ShellInit shellInit,
ShellCommandHandler shellCommandHandler,
CompatUIController compatUI,
@@ -180,6 +182,10 @@ public abstract class WMShellBaseModule {
Optional<RecentTasksController> recentTasksOptional,
@ShellMainThread ShellExecutor mainExecutor
) {
+ if (!context.getResources().getBoolean(R.bool.config_registerShellTaskOrganizerOnInit)) {
+ // TODO(b/238217847): Force override shell init if registration is disabled
+ shellInit = new ShellInit(mainExecutor);
+ }
return new ShellTaskOrganizer(shellInit, shellCommandHandler, compatUI,
unfoldAnimationController, recentTasksOptional, mainExecutor);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
index 4c927b6e84b8..dbb2948de5db 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
@@ -18,13 +18,11 @@ package com.android.wm.shell.transition;
import static android.app.ActivityOptions.ANIM_CLIP_REVEAL;
import static android.app.ActivityOptions.ANIM_CUSTOM;
-import static android.app.ActivityOptions.ANIM_FROM_STYLE;
import static android.app.ActivityOptions.ANIM_NONE;
import static android.app.ActivityOptions.ANIM_OPEN_CROSS_PROFILE_APPS;
import static android.app.ActivityOptions.ANIM_SCALE_UP;
import static android.app.ActivityOptions.ANIM_THUMBNAIL_SCALE_DOWN;
import static android.app.ActivityOptions.ANIM_THUMBNAIL_SCALE_UP;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_DREAM;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_RESOURCE_UPDATED;
import static android.app.admin.DevicePolicyManager.EXTRA_RESOURCE_TYPE;
@@ -43,10 +41,11 @@ import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_RELAUNCH;
import static android.view.WindowManager.TRANSIT_TO_BACK;
import static android.view.WindowManager.TRANSIT_TO_FRONT;
-import static android.view.WindowManager.transitTypeToString;
import static android.window.TransitionInfo.FLAG_CROSS_PROFILE_OWNER_THUMBNAIL;
import static android.window.TransitionInfo.FLAG_CROSS_PROFILE_WORK_THUMBNAIL;
import static android.window.TransitionInfo.FLAG_DISPLAY_HAS_ALERT_WINDOWS;
+import static android.window.TransitionInfo.FLAG_FILLS_TASK;
+import static android.window.TransitionInfo.FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY;
import static android.window.TransitionInfo.FLAG_IS_DISPLAY;
import static android.window.TransitionInfo.FLAG_IS_VOICE_INTERACTION;
import static android.window.TransitionInfo.FLAG_IS_WALLPAPER;
@@ -59,6 +58,10 @@ import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITI
import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITION_INTRA_OPEN;
import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITION_NONE;
import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITION_OPEN;
+import static com.android.wm.shell.transition.TransitionAnimationHelper.addBackgroundToTransition;
+import static com.android.wm.shell.transition.TransitionAnimationHelper.getTransitionBackgroundColorIfSet;
+import static com.android.wm.shell.transition.TransitionAnimationHelper.loadAttributeAnimation;
+import static com.android.wm.shell.transition.TransitionAnimationHelper.sDisableCustomTaskAnimationProperty;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -74,7 +77,6 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Canvas;
-import android.graphics.Color;
import android.graphics.Insets;
import android.graphics.Paint;
import android.graphics.PixelFormat;
@@ -84,7 +86,6 @@ import android.graphics.drawable.Drawable;
import android.hardware.HardwareBuffer;
import android.os.Handler;
import android.os.IBinder;
-import android.os.SystemProperties;
import android.os.UserHandle;
import android.util.ArrayMap;
import android.view.Choreographer;
@@ -122,21 +123,6 @@ import java.util.function.Consumer;
public class DefaultTransitionHandler implements Transitions.TransitionHandler {
private static final int MAX_ANIMATION_DURATION = 3000;
- /**
- * Restrict ability of activities overriding transition animation in a way such that
- * an activity can do it only when the transition happens within a same task.
- *
- * @see android.app.Activity#overridePendingTransition(int, int)
- */
- private static final String DISABLE_CUSTOM_TASK_ANIMATION_PROPERTY =
- "persist.wm.disable_custom_task_animation";
-
- /**
- * @see #DISABLE_CUSTOM_TASK_ANIMATION_PROPERTY
- */
- static boolean sDisableCustomTaskAnimationProperty =
- SystemProperties.getBoolean(DISABLE_CUSTOM_TASK_ANIMATION_PROPERTY, true);
-
private final TransactionPool mTransactionPool;
private final DisplayController mDisplayController;
private final Context mContext;
@@ -384,8 +370,10 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
change.getEndAbsBounds().top - info.getRootOffset().y);
// Seamless display transition doesn't need to animate.
if (isSeamlessDisplayChange) continue;
- if (isTask) {
- // Skip non-tasks since those usually have null bounds.
+ if (isTask || (change.hasFlags(FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY)
+ && !change.hasFlags(FLAG_FILLS_TASK))) {
+ // Update Task and embedded split window crop bounds, otherwise we may see crop
+ // on previous bounds during the rotation animation.
startTransaction.setWindowCrop(change.getLeash(),
change.getEndAbsBounds().width(), change.getEndAbsBounds().height());
}
@@ -431,22 +419,8 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
cornerRadius = 0;
}
- if (a.getShowBackdrop()) {
- if (info.getAnimationOptions().getBackgroundColor() != 0) {
- // If available use the background color provided through AnimationOptions
- backgroundColorForTransition =
- info.getAnimationOptions().getBackgroundColor();
- } else if (a.getBackdropColor() != 0) {
- // Otherwise fallback on the background color provided through the animation
- // definition.
- backgroundColorForTransition = a.getBackdropColor();
- } else if (change.getBackgroundColor() != 0) {
- // Otherwise default to the window's background color if provided through
- // the theme as the background color for the animation - the top most window
- // with a valid background color and showBackground set takes precedence.
- backgroundColorForTransition = change.getBackgroundColor();
- }
- }
+ backgroundColorForTransition = getTransitionBackgroundColorIfSet(info, change, a,
+ backgroundColorForTransition);
boolean delayedEdgeExtension = false;
if (!isTask && a.hasExtension()) {
@@ -668,29 +642,6 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
return edgeExtensionLayer;
}
- private void addBackgroundToTransition(
- @NonNull SurfaceControl rootLeash,
- @ColorInt int color,
- @NonNull SurfaceControl.Transaction startTransaction,
- @NonNull SurfaceControl.Transaction finishTransaction
- ) {
- final Color bgColor = Color.valueOf(color);
- final float[] colorArray = new float[] { bgColor.red(), bgColor.green(), bgColor.blue() };
-
- final SurfaceControl animationBackgroundSurface = new SurfaceControl.Builder()
- .setName("Animation Background")
- .setParent(rootLeash)
- .setColorLayer()
- .setOpaque(true)
- .build();
-
- startTransaction
- .setLayer(animationBackgroundSurface, Integer.MIN_VALUE)
- .setColor(animationBackgroundSurface, colorArray)
- .show(animationBackgroundSurface);
- finishTransaction.remove(animationBackgroundSurface);
- }
-
@Nullable
@Override
public WindowContainerTransaction handleRequest(@NonNull IBinder transition,
@@ -704,9 +655,9 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
}
@Nullable
- private Animation loadAnimation(TransitionInfo info, TransitionInfo.Change change,
- int wallpaperTransit) {
- Animation a = null;
+ private Animation loadAnimation(@NonNull TransitionInfo info,
+ @NonNull TransitionInfo.Change change, int wallpaperTransit) {
+ Animation a;
final int type = info.getType();
final int flags = info.getFlags();
@@ -717,12 +668,10 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
final boolean isTask = change.getTaskInfo() != null;
final TransitionInfo.AnimationOptions options = info.getAnimationOptions();
final int overrideType = options != null ? options.getType() : ANIM_NONE;
- final boolean canCustomContainer = isTask ? !sDisableCustomTaskAnimationProperty : true;
+ final boolean canCustomContainer = !isTask || !sDisableCustomTaskAnimationProperty;
final Rect endBounds = Transitions.isClosingType(changeMode)
? mRotator.getEndBoundsInStartRotation(change)
: change.getEndAbsBounds();
- final boolean isDream =
- isTask && change.getTaskInfo().topActivityType == ACTIVITY_TYPE_DREAM;
if (info.isKeyguardGoingAway()) {
a = mTransitionAnimation.loadKeyguardExitAnimation(flags,
@@ -763,87 +712,7 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
// This received a transferred starting window, so don't animate
return null;
} else {
- int animAttr = 0;
- boolean translucent = false;
- if (isDream) {
- if (type == TRANSIT_OPEN) {
- animAttr = enter
- ? R.styleable.WindowAnimation_dreamActivityOpenEnterAnimation
- : R.styleable.WindowAnimation_dreamActivityOpenExitAnimation;
- } else if (type == TRANSIT_CLOSE) {
- animAttr = enter
- ? 0
- : R.styleable.WindowAnimation_dreamActivityCloseExitAnimation;
- }
- } else if (wallpaperTransit == WALLPAPER_TRANSITION_INTRA_OPEN) {
- animAttr = enter
- ? R.styleable.WindowAnimation_wallpaperIntraOpenEnterAnimation
- : R.styleable.WindowAnimation_wallpaperIntraOpenExitAnimation;
- } else if (wallpaperTransit == WALLPAPER_TRANSITION_INTRA_CLOSE) {
- animAttr = enter
- ? R.styleable.WindowAnimation_wallpaperIntraCloseEnterAnimation
- : R.styleable.WindowAnimation_wallpaperIntraCloseExitAnimation;
- } else if (wallpaperTransit == WALLPAPER_TRANSITION_OPEN) {
- animAttr = enter
- ? R.styleable.WindowAnimation_wallpaperOpenEnterAnimation
- : R.styleable.WindowAnimation_wallpaperOpenExitAnimation;
- } else if (wallpaperTransit == WALLPAPER_TRANSITION_CLOSE) {
- animAttr = enter
- ? R.styleable.WindowAnimation_wallpaperCloseEnterAnimation
- : R.styleable.WindowAnimation_wallpaperCloseExitAnimation;
- } else if (type == TRANSIT_OPEN) {
- // We will translucent open animation for translucent activities and tasks. Choose
- // WindowAnimation_activityOpenEnterAnimation and set translucent here, then
- // TransitionAnimation loads appropriate animation later.
- if ((changeFlags & FLAG_TRANSLUCENT) != 0 && enter) {
- translucent = true;
- }
- if (isTask && !translucent) {
- animAttr = enter
- ? R.styleable.WindowAnimation_taskOpenEnterAnimation
- : R.styleable.WindowAnimation_taskOpenExitAnimation;
- } else {
- animAttr = enter
- ? R.styleable.WindowAnimation_activityOpenEnterAnimation
- : R.styleable.WindowAnimation_activityOpenExitAnimation;
- }
- } else if (type == TRANSIT_TO_FRONT) {
- animAttr = enter
- ? R.styleable.WindowAnimation_taskToFrontEnterAnimation
- : R.styleable.WindowAnimation_taskToFrontExitAnimation;
- } else if (type == TRANSIT_CLOSE) {
- if (isTask) {
- animAttr = enter
- ? R.styleable.WindowAnimation_taskCloseEnterAnimation
- : R.styleable.WindowAnimation_taskCloseExitAnimation;
- } else {
- if ((changeFlags & FLAG_TRANSLUCENT) != 0 && !enter) {
- translucent = true;
- }
- animAttr = enter
- ? R.styleable.WindowAnimation_activityCloseEnterAnimation
- : R.styleable.WindowAnimation_activityCloseExitAnimation;
- }
- } else if (type == TRANSIT_TO_BACK) {
- animAttr = enter
- ? R.styleable.WindowAnimation_taskToBackEnterAnimation
- : R.styleable.WindowAnimation_taskToBackExitAnimation;
- }
-
- if (animAttr != 0) {
- if (overrideType == ANIM_FROM_STYLE && canCustomContainer) {
- a = mTransitionAnimation
- .loadAnimationAttr(options.getPackageName(), options.getAnimations(),
- animAttr, translucent);
- } else {
- a = mTransitionAnimation.loadDefaultAnimationAttr(animAttr, translucent);
- }
- }
-
- ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS,
- "loadAnimation: anim=%s animAttr=0x%x type=%s isEntrance=%b", a, animAttr,
- transitTypeToString(type),
- enter);
+ a = loadAttributeAnimation(info, change, wallpaperTransit, mTransitionAnimation);
}
if (a != null) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java
new file mode 100644
index 000000000000..efee6f40b53e
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2022 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.wm.shell.transition;
+
+import static android.app.ActivityOptions.ANIM_FROM_STYLE;
+import static android.app.ActivityOptions.ANIM_NONE;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_DREAM;
+import static android.view.WindowManager.TRANSIT_CLOSE;
+import static android.view.WindowManager.TRANSIT_OPEN;
+import static android.view.WindowManager.TRANSIT_TO_BACK;
+import static android.view.WindowManager.TRANSIT_TO_FRONT;
+import static android.view.WindowManager.transitTypeToString;
+import static android.window.TransitionInfo.FLAG_TRANSLUCENT;
+
+import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITION_CLOSE;
+import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITION_INTRA_CLOSE;
+import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITION_INTRA_OPEN;
+import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITION_OPEN;
+
+import android.annotation.ColorInt;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.graphics.Color;
+import android.os.SystemProperties;
+import android.view.SurfaceControl;
+import android.view.animation.Animation;
+import android.window.TransitionInfo;
+
+import com.android.internal.R;
+import com.android.internal.policy.TransitionAnimation;
+import com.android.internal.protolog.common.ProtoLog;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
+
+/** The helper class that provides methods for adding styles to transition animations. */
+public class TransitionAnimationHelper {
+
+ /**
+ * Restrict ability of activities overriding transition animation in a way such that
+ * an activity can do it only when the transition happens within a same task.
+ *
+ * @see android.app.Activity#overridePendingTransition(int, int)
+ */
+ private static final String DISABLE_CUSTOM_TASK_ANIMATION_PROPERTY =
+ "persist.wm.disable_custom_task_animation";
+
+ /**
+ * @see #DISABLE_CUSTOM_TASK_ANIMATION_PROPERTY
+ */
+ static final boolean sDisableCustomTaskAnimationProperty =
+ SystemProperties.getBoolean(DISABLE_CUSTOM_TASK_ANIMATION_PROPERTY, true);
+
+ /** Loads the animation that is defined through attribute id for the given transition. */
+ @Nullable
+ public static Animation loadAttributeAnimation(@NonNull TransitionInfo info,
+ @NonNull TransitionInfo.Change change, int wallpaperTransit,
+ @NonNull TransitionAnimation transitionAnimation) {
+ final int type = info.getType();
+ final int changeMode = change.getMode();
+ final int changeFlags = change.getFlags();
+ final boolean enter = Transitions.isOpeningType(changeMode);
+ final boolean isTask = change.getTaskInfo() != null;
+ final TransitionInfo.AnimationOptions options = info.getAnimationOptions();
+ final int overrideType = options != null ? options.getType() : ANIM_NONE;
+ final boolean canCustomContainer = !isTask || !sDisableCustomTaskAnimationProperty;
+ final boolean isDream =
+ isTask && change.getTaskInfo().topActivityType == ACTIVITY_TYPE_DREAM;
+ int animAttr = 0;
+ boolean translucent = false;
+ if (isDream) {
+ if (type == TRANSIT_OPEN) {
+ animAttr = enter
+ ? R.styleable.WindowAnimation_dreamActivityOpenEnterAnimation
+ : R.styleable.WindowAnimation_dreamActivityOpenExitAnimation;
+ } else if (type == TRANSIT_CLOSE) {
+ animAttr = enter
+ ? 0
+ : R.styleable.WindowAnimation_dreamActivityCloseExitAnimation;
+ }
+ } else if (wallpaperTransit == WALLPAPER_TRANSITION_INTRA_OPEN) {
+ animAttr = enter
+ ? R.styleable.WindowAnimation_wallpaperIntraOpenEnterAnimation
+ : R.styleable.WindowAnimation_wallpaperIntraOpenExitAnimation;
+ } else if (wallpaperTransit == WALLPAPER_TRANSITION_INTRA_CLOSE) {
+ animAttr = enter
+ ? R.styleable.WindowAnimation_wallpaperIntraCloseEnterAnimation
+ : R.styleable.WindowAnimation_wallpaperIntraCloseExitAnimation;
+ } else if (wallpaperTransit == WALLPAPER_TRANSITION_OPEN) {
+ animAttr = enter
+ ? R.styleable.WindowAnimation_wallpaperOpenEnterAnimation
+ : R.styleable.WindowAnimation_wallpaperOpenExitAnimation;
+ } else if (wallpaperTransit == WALLPAPER_TRANSITION_CLOSE) {
+ animAttr = enter
+ ? R.styleable.WindowAnimation_wallpaperCloseEnterAnimation
+ : R.styleable.WindowAnimation_wallpaperCloseExitAnimation;
+ } else if (type == TRANSIT_OPEN) {
+ // We will translucent open animation for translucent activities and tasks. Choose
+ // WindowAnimation_activityOpenEnterAnimation and set translucent here, then
+ // TransitionAnimation loads appropriate animation later.
+ if ((changeFlags & FLAG_TRANSLUCENT) != 0 && enter) {
+ translucent = true;
+ }
+ if (isTask && !translucent) {
+ animAttr = enter
+ ? R.styleable.WindowAnimation_taskOpenEnterAnimation
+ : R.styleable.WindowAnimation_taskOpenExitAnimation;
+ } else {
+ animAttr = enter
+ ? R.styleable.WindowAnimation_activityOpenEnterAnimation
+ : R.styleable.WindowAnimation_activityOpenExitAnimation;
+ }
+ } else if (type == TRANSIT_TO_FRONT) {
+ animAttr = enter
+ ? R.styleable.WindowAnimation_taskToFrontEnterAnimation
+ : R.styleable.WindowAnimation_taskToFrontExitAnimation;
+ } else if (type == TRANSIT_CLOSE) {
+ if (isTask) {
+ animAttr = enter
+ ? R.styleable.WindowAnimation_taskCloseEnterAnimation
+ : R.styleable.WindowAnimation_taskCloseExitAnimation;
+ } else {
+ if ((changeFlags & FLAG_TRANSLUCENT) != 0 && !enter) {
+ translucent = true;
+ }
+ animAttr = enter
+ ? R.styleable.WindowAnimation_activityCloseEnterAnimation
+ : R.styleable.WindowAnimation_activityCloseExitAnimation;
+ }
+ } else if (type == TRANSIT_TO_BACK) {
+ animAttr = enter
+ ? R.styleable.WindowAnimation_taskToBackEnterAnimation
+ : R.styleable.WindowAnimation_taskToBackExitAnimation;
+ }
+
+ Animation a = null;
+ if (animAttr != 0) {
+ if (overrideType == ANIM_FROM_STYLE && canCustomContainer) {
+ a = transitionAnimation
+ .loadAnimationAttr(options.getPackageName(), options.getAnimations(),
+ animAttr, translucent);
+ } else {
+ a = transitionAnimation.loadDefaultAnimationAttr(animAttr, translucent);
+ }
+ }
+
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS,
+ "loadAnimation: anim=%s animAttr=0x%x type=%s isEntrance=%b", a, animAttr,
+ transitTypeToString(type),
+ enter);
+ return a;
+ }
+
+ /**
+ * Gets the background {@link ColorInt} for the given transition animation if it is set.
+ *
+ * @param defaultColor {@link ColorInt} to return if there is no background color specified by
+ * the given transition animation.
+ */
+ @ColorInt
+ public static int getTransitionBackgroundColorIfSet(@NonNull TransitionInfo info,
+ @NonNull TransitionInfo.Change change, @NonNull Animation a,
+ @ColorInt int defaultColor) {
+ if (!a.getShowBackdrop()) {
+ return defaultColor;
+ }
+ if (info.getAnimationOptions() != null
+ && info.getAnimationOptions().getBackgroundColor() != 0) {
+ // If available use the background color provided through AnimationOptions
+ return info.getAnimationOptions().getBackgroundColor();
+ } else if (a.getBackdropColor() != 0) {
+ // Otherwise fallback on the background color provided through the animation
+ // definition.
+ return a.getBackdropColor();
+ } else if (change.getBackgroundColor() != 0) {
+ // Otherwise default to the window's background color if provided through
+ // the theme as the background color for the animation - the top most window
+ // with a valid background color and showBackground set takes precedence.
+ return change.getBackgroundColor();
+ }
+ return defaultColor;
+ }
+
+ /**
+ * Adds the given {@code backgroundColor} as the background color to the transition animation.
+ */
+ public static void addBackgroundToTransition(@NonNull SurfaceControl rootLeash,
+ @ColorInt int backgroundColor, @NonNull SurfaceControl.Transaction startTransaction,
+ @NonNull SurfaceControl.Transaction finishTransaction) {
+ if (backgroundColor == 0) {
+ // No background color.
+ return;
+ }
+ final Color bgColor = Color.valueOf(backgroundColor);
+ final float[] colorArray = new float[] { bgColor.red(), bgColor.green(), bgColor.blue() };
+ final SurfaceControl animationBackgroundSurface = new SurfaceControl.Builder()
+ .setName("Animation Background")
+ .setParent(rootLeash)
+ .setColorLayer()
+ .setOpaque(true)
+ .build();
+ startTransaction
+ .setLayer(animationBackgroundSurface, Integer.MIN_VALUE)
+ .setColor(animationBackgroundSurface, colorArray)
+ .show(animationBackgroundSurface);
+ finishTransaction.remove(animationBackgroundSurface);
+ }
+}
diff --git a/native/android/surface_control.cpp b/native/android/surface_control.cpp
index 1ebdc273931b..795af8a58351 100644
--- a/native/android/surface_control.cpp
+++ b/native/android/surface_control.cpp
@@ -300,7 +300,7 @@ void ASurfaceTransaction_setOnComplete(ASurfaceTransaction* aSurfaceTransaction,
auto& aSurfaceControlStats = aSurfaceTransactionStats.aSurfaceControlStats;
for (const auto& [surfaceControl, latchTime, acquireTimeOrFence, presentFence,
- previousReleaseFence, transformHint, frameEvents] : surfaceControlStats) {
+ previousReleaseFence, transformHint, frameEvents, ignore] : surfaceControlStats) {
ASurfaceControl* aSurfaceControl = reinterpret_cast<ASurfaceControl*>(surfaceControl.get());
aSurfaceControlStats[aSurfaceControl].acquireTimeOrFence = acquireTimeOrFence;
aSurfaceControlStats[aSurfaceControl].previousReleaseFence = previousReleaseFence;
@@ -650,7 +650,7 @@ void ASurfaceTransaction_setOnCommit(ASurfaceTransaction* aSurfaceTransaction, v
auto& aSurfaceControlStats = aSurfaceTransactionStats.aSurfaceControlStats;
for (const auto& [surfaceControl, latchTime, acquireTimeOrFence, presentFence,
- previousReleaseFence, transformHint, frameEvents] :
+ previousReleaseFence, transformHint, frameEvents, ignore] :
surfaceControlStats) {
ASurfaceControl* aSurfaceControl =
reinterpret_cast<ASurfaceControl*>(surfaceControl.get());
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/NavigationEdgeBackPlugin.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/NavigationEdgeBackPlugin.java
index 12372593b62f..506ccf3c2437 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/NavigationEdgeBackPlugin.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/NavigationEdgeBackPlugin.java
@@ -61,5 +61,13 @@ public interface NavigationEdgeBackPlugin extends Plugin {
/** Indicates that the gesture was cancelled and the system should not go back. */
void cancelBack();
+
+ /**
+ * Indicates if back will be triggered if committed in current state.
+ *
+ * @param triggerBack if back will be triggered in current state.
+ */
+ // TODO(b/247883311): Remove default impl once SwipeBackGestureHandler overrides this.
+ default void setTriggerBack(boolean triggerBack) {}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
index 67b683ec643a..2e13903814a5 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
@@ -455,6 +455,7 @@ public class ScreenDecorations extends CoreStartable implements Tunable , Dumpab
}
}
+ boolean needToUpdateProviderViews = false;
final String newUniqueId = mDisplayInfo.uniqueId;
if (!Objects.equals(newUniqueId, mDisplayUniqueId)) {
mDisplayUniqueId = newUniqueId;
@@ -472,6 +473,37 @@ public class ScreenDecorations extends CoreStartable implements Tunable , Dumpab
setupDecorations();
return;
}
+
+ if (mScreenDecorHwcLayer != null) {
+ updateHwLayerRoundedCornerDrawable();
+ updateHwLayerRoundedCornerExistAndSize();
+ }
+ needToUpdateProviderViews = true;
+ }
+
+ final float newRatio = getPhysicalPixelDisplaySizeRatio();
+ if (mRoundedCornerResDelegate.getPhysicalPixelDisplaySizeRatio() != newRatio) {
+ mRoundedCornerResDelegate.setPhysicalPixelDisplaySizeRatio(newRatio);
+ if (mScreenDecorHwcLayer != null) {
+ updateHwLayerRoundedCornerExistAndSize();
+ }
+ needToUpdateProviderViews = true;
+ }
+
+ if (needToUpdateProviderViews) {
+ updateOverlayProviderViews(null);
+ } else {
+ updateOverlayProviderViews(new Integer[] {
+ mFaceScanningViewId,
+ R.id.display_cutout,
+ R.id.display_cutout_left,
+ R.id.display_cutout_right,
+ R.id.display_cutout_bottom,
+ });
+ }
+
+ if (mScreenDecorHwcLayer != null) {
+ mScreenDecorHwcLayer.onDisplayChanged(newUniqueId);
}
}
};
@@ -1037,8 +1069,6 @@ public class ScreenDecorations extends CoreStartable implements Tunable , Dumpab
&& (newRotation != mRotation || displayModeChanged(mDisplayMode, newMod))) {
mRotation = newRotation;
mDisplayMode = newMod;
- mRoundedCornerResDelegate.setPhysicalPixelDisplaySizeRatio(
- getPhysicalPixelDisplaySizeRatio());
if (mScreenDecorHwcLayer != null) {
mScreenDecorHwcLayer.pendingConfigChange = false;
mScreenDecorHwcLayer.updateRotation(mRotation);
diff --git a/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerResDelegate.kt b/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerResDelegate.kt
index 8b4aeefb6ed4..a25286438387 100644
--- a/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerResDelegate.kt
+++ b/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerResDelegate.kt
@@ -78,18 +78,23 @@ class RoundedCornerResDelegate(
reloadMeasures()
}
+ private fun reloadAll(newReloadToken: Int) {
+ if (reloadToken == newReloadToken) {
+ return
+ }
+ reloadToken = newReloadToken
+ reloadRes()
+ reloadMeasures()
+ }
+
fun updateDisplayUniqueId(newDisplayUniqueId: String?, newReloadToken: Int?) {
if (displayUniqueId != newDisplayUniqueId) {
displayUniqueId = newDisplayUniqueId
newReloadToken ?.let { reloadToken = it }
reloadRes()
reloadMeasures()
- } else if (newReloadToken != null) {
- if (reloadToken == newReloadToken) {
- return
- }
- reloadToken = newReloadToken
- reloadMeasures()
+ } else {
+ newReloadToken?.let { reloadAll(it) }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
index d605c1a42ec0..0f1338e4e872 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
@@ -303,6 +303,13 @@ public class EdgeBackGestureHandler extends CurrentUserTracker
mOverviewProxyService.notifyBackAction(false, (int) mDownPoint.x,
(int) mDownPoint.y, false /* isButton */, !mIsOnLeftEdge);
}
+
+ @Override
+ public void setTriggerBack(boolean triggerBack) {
+ if (mBackAnimation != null) {
+ mBackAnimation.setTriggerBack(triggerBack);
+ }
+ }
};
private final SysUiState.SysUiStateCallback mSysUiStateCallback =
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationBarEdgePanel.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationBarEdgePanel.java
index 122852f7d07a..24efc762b39b 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationBarEdgePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationBarEdgePanel.java
@@ -880,6 +880,7 @@ public class NavigationBarEdgePanel extends View implements NavigationEdgeBackPl
// Whenever the trigger back state changes the existing translation animation should be
// cancelled
mTranslationAnimation.cancel();
+ mBackCallback.setTriggerBack(mTriggerBack);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooterUtils.java b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooterUtils.java
index bd75c75faa00..ae6ed2008a77 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooterUtils.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooterUtils.java
@@ -444,7 +444,7 @@ public class QSSecurityFooterUtils implements DialogInterface.OnClickListener {
mShouldUseSettingsButton.set(false);
mBgHandler.post(() -> {
String settingsButtonText = getSettingsButton();
- final View dialogView = createDialogView();
+ final View dialogView = createDialogView(quickSettingsContext);
mMainHandler.post(() -> {
mDialog = new SystemUIDialog(quickSettingsContext, 0);
mDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
@@ -469,14 +469,14 @@ public class QSSecurityFooterUtils implements DialogInterface.OnClickListener {
}
@VisibleForTesting
- View createDialogView() {
+ View createDialogView(Context quickSettingsContext) {
if (mSecurityController.isParentalControlsEnabled()) {
return createParentalControlsDialogView();
}
- return createOrganizationDialogView();
+ return createOrganizationDialogView(quickSettingsContext);
}
- private View createOrganizationDialogView() {
+ private View createOrganizationDialogView(Context quickSettingsContext) {
final boolean isDeviceManaged = mSecurityController.isDeviceManaged();
final boolean hasWorkProfile = mSecurityController.hasWorkProfile();
final CharSequence deviceOwnerOrganization =
@@ -487,7 +487,7 @@ public class QSSecurityFooterUtils implements DialogInterface.OnClickListener {
final String vpnName = mSecurityController.getPrimaryVpnName();
final String vpnNameWorkProfile = mSecurityController.getWorkProfileVpnName();
- View dialogView = LayoutInflater.from(mContext)
+ View dialogView = LayoutInflater.from(quickSettingsContext)
.inflate(R.layout.quick_settings_footer_dialog, null, false);
// device management section
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index e61794b0243e..9d5392af3127 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -730,7 +730,9 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
private void setDozing(boolean dozing) {
if (mDozing != dozing) {
mDozing = dozing;
- reset(true /* hideBouncerWhenShowing */);
+ if (dozing || mBouncer.needsFullscreenBouncer() || mOccluded) {
+ reset(dozing /* hideBouncerWhenShowing */);
+ }
updateStates();
if (!dozing) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
index 5a26d05d7b37..df10dfe9f160 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
@@ -1005,13 +1005,18 @@ public class ScreenDecorationsTest extends SysuiTestCase {
assertEquals(new Size(3, 3), resDelegate.getTopRoundedSize());
assertEquals(new Size(4, 4), resDelegate.getBottomRoundedSize());
- doReturn(2f).when(mScreenDecorations).getPhysicalPixelDisplaySizeRatio();
+ setupResources(20 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
+ getTestsDrawable(com.android.systemui.tests.R.drawable.rounded4px)
+ /* roundedTopDrawable */,
+ getTestsDrawable(com.android.systemui.tests.R.drawable.rounded5px)
+ /* roundedBottomDrawable */,
+ 0 /* roundedPadding */, true /* privacyDot */, false /* faceScanning*/);
mDisplayInfo.rotation = Surface.ROTATION_270;
mScreenDecorations.onConfigurationChanged(null);
- assertEquals(new Size(6, 6), resDelegate.getTopRoundedSize());
- assertEquals(new Size(8, 8), resDelegate.getBottomRoundedSize());
+ assertEquals(new Size(4, 4), resDelegate.getTopRoundedSize());
+ assertEquals(new Size(5, 5), resDelegate.getBottomRoundedSize());
}
@Test
@@ -1288,6 +1293,51 @@ public class ScreenDecorationsTest extends SysuiTestCase {
}
@Test
+ public void testOnDisplayChanged_hwcLayer() {
+ setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
+ null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
+ 0 /* roundedPadding */, false /* privacyDot */, false /* faceScanning */);
+ final DisplayDecorationSupport decorationSupport = new DisplayDecorationSupport();
+ decorationSupport.format = PixelFormat.R_8;
+ doReturn(decorationSupport).when(mDisplay).getDisplayDecorationSupport();
+
+ // top cutout
+ mMockCutoutList.add(new CutoutDecorProviderImpl(BOUNDS_POSITION_TOP));
+
+ mScreenDecorations.start();
+
+ final ScreenDecorHwcLayer hwcLayer = mScreenDecorations.mScreenDecorHwcLayer;
+ spyOn(hwcLayer);
+ doReturn(mDisplay).when(hwcLayer).getDisplay();
+
+ mScreenDecorations.mDisplayListener.onDisplayChanged(1);
+
+ verify(hwcLayer, times(1)).onDisplayChanged(any());
+ }
+
+ @Test
+ public void testOnDisplayChanged_nonHwcLayer() {
+ setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
+ null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
+ 0 /* roundedPadding */, false /* privacyDot */, false /* faceScanning */);
+
+ // top cutout
+ mMockCutoutList.add(new CutoutDecorProviderImpl(BOUNDS_POSITION_TOP));
+
+ mScreenDecorations.start();
+
+ final ScreenDecorations.DisplayCutoutView cutoutView = (ScreenDecorations.DisplayCutoutView)
+ mScreenDecorations.getOverlayView(R.id.display_cutout);
+ assertNotNull(cutoutView);
+ spyOn(cutoutView);
+ doReturn(mDisplay).when(cutoutView).getDisplay();
+
+ mScreenDecorations.mDisplayListener.onDisplayChanged(1);
+
+ verify(cutoutView, times(1)).onDisplayChanged(any());
+ }
+
+ @Test
public void testHasSameProvidersWithNullOverlays() {
setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/decor/RoundedCornerResDelegateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/decor/RoundedCornerResDelegateTest.kt
index 93a1868b72f5..f93336134900 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/decor/RoundedCornerResDelegateTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/decor/RoundedCornerResDelegateTest.kt
@@ -24,11 +24,12 @@ import androidx.annotation.DrawableRes
import androidx.test.filters.SmallTest
import com.android.internal.R as InternalR
import com.android.systemui.R as SystemUIR
-import com.android.systemui.SysuiTestCase
import com.android.systemui.tests.R
+import com.android.systemui.SysuiTestCase
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Test
+
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.MockitoAnnotations
@@ -101,11 +102,14 @@ class RoundedCornerResDelegateTest : SysuiTestCase() {
assertEquals(Size(3, 3), roundedCornerResDelegate.topRoundedSize)
assertEquals(Size(4, 4), roundedCornerResDelegate.bottomRoundedSize)
- roundedCornerResDelegate.physicalPixelDisplaySizeRatio = 2f
+ setupResources(radius = 100,
+ roundedTopDrawable = getTestsDrawable(R.drawable.rounded4px),
+ roundedBottomDrawable = getTestsDrawable(R.drawable.rounded5px))
+
roundedCornerResDelegate.updateDisplayUniqueId(null, 1)
- assertEquals(Size(6, 6), roundedCornerResDelegate.topRoundedSize)
- assertEquals(Size(8, 8), roundedCornerResDelegate.bottomRoundedSize)
+ assertEquals(Size(4, 4), roundedCornerResDelegate.topRoundedSize)
+ assertEquals(Size(5, 5), roundedCornerResDelegate.bottomRoundedSize)
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java
index 233c267c3be0..1c686c66e31e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java
@@ -726,7 +726,7 @@ public class QSSecurityFooterTest extends SysuiTestCase {
when(mSecurityController.isParentalControlsEnabled()).thenReturn(true);
when(mSecurityController.getLabel(any())).thenReturn(PARENTAL_CONTROLS_LABEL);
- View view = mFooterUtils.createDialogView();
+ View view = mFooterUtils.createDialogView(getContext());
TextView textView = (TextView) view.findViewById(R.id.parental_controls_title);
assertEquals(PARENTAL_CONTROLS_LABEL, textView.getText());
}
@@ -749,7 +749,7 @@ public class QSSecurityFooterTest extends SysuiTestCase {
when(mSecurityController.getDeviceOwnerType(DEVICE_OWNER_COMPONENT))
.thenReturn(DEVICE_OWNER_TYPE_FINANCED);
- View view = mFooterUtils.createDialogView();
+ View view = mFooterUtils.createDialogView(getContext());
TextView managementSubtitle = view.findViewById(R.id.device_management_subtitle);
assertEquals(View.VISIBLE, managementSubtitle.getVisibility());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
index ee4b9d9c93f2..dcce61b86ced 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
@@ -26,7 +26,6 @@ import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -526,21 +525,4 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
mBouncerExpansionCallback.onVisibilityChanged(false);
verify(mCentralSurfaces).setBouncerShowingOverDream(false);
}
-
- @Test
- public void testSetDozing_Dozing() {
- clearInvocations(mBouncer);
- mStatusBarKeyguardViewManager.onDozingChanged(true);
- // Once when shown and once with dozing changed.
- verify(mBouncer, times(1)).hide(false);
- }
-
- @Test
- public void testSetDozing_notDozing() {
- mStatusBarKeyguardViewManager.onDozingChanged(true);
- clearInvocations(mBouncer);
- mStatusBarKeyguardViewManager.onDozingChanged(false);
- // Once when shown and twice with dozing changed.
- verify(mBouncer, times(1)).hide(false);
- }
}
diff --git a/services/companion/java/com/android/server/companion/presence/BleCompanionDeviceScanner.java b/services/companion/java/com/android/server/companion/presence/BleCompanionDeviceScanner.java
index ad09f7cd3dde..33f1b4282e97 100644
--- a/services/companion/java/com/android/server/companion/presence/BleCompanionDeviceScanner.java
+++ b/services/companion/java/com/android/server/companion/presence/BleCompanionDeviceScanner.java
@@ -184,13 +184,21 @@ class BleCompanionDeviceScanner implements AssociationStore.OnChangeListener {
@MainThread
private void startScan() {
enforceInitialized();
- // This method should not be called if scan is already in progress.
- if (mScanning) throw new IllegalStateException("Scan is already in progress.");
- // Neither should this method be called if the adapter is not available.
- if (mBleScanner == null) throw new IllegalStateException("BLE is not available.");
if (DEBUG) Log.i(TAG, "startScan()");
+ // This method should not be called if scan is already in progress.
+ if (mScanning) {
+ Slog.w(TAG, "Scan is already in progress.");
+ return;
+ }
+
+ // Neither should this method be called if the adapter is not available.
+ if (mBleScanner == null) {
+ Slog.w(TAG, "BLE is not available.");
+ return;
+ }
+
// Collect MAC addresses from all associations.
final Set<String> macAddresses = new HashSet<>();
for (AssociationInfo association : mAssociationStore.getAssociations()) {
@@ -221,8 +229,18 @@ class BleCompanionDeviceScanner implements AssociationStore.OnChangeListener {
filters.add(filter);
}
- mBleScanner.startScan(filters, SCAN_SETTINGS, mScanCallback);
- mScanning = true;
+ // BluetoothLeScanner will throw an IllegalStateException if startScan() is called while LE
+ // is not enabled.
+ if (mBtAdapter.isLeEnabled()) {
+ try {
+ mBleScanner.startScan(filters, SCAN_SETTINGS, mScanCallback);
+ mScanning = true;
+ } catch (IllegalStateException e) {
+ Slog.w(TAG, "Exception while starting BLE scanning", e);
+ }
+ } else {
+ Slog.w(TAG, "BLE scanning is not turned on");
+ }
}
private void stopScanIfNeeded() {
@@ -240,11 +258,11 @@ class BleCompanionDeviceScanner implements AssociationStore.OnChangeListener {
if (mBtAdapter.isLeEnabled()) {
try {
mBleScanner.stopScan(mScanCallback);
- } catch (RuntimeException e) {
- // Just to be sure not to crash system server here if BluetoothLeScanner throws
- // another RuntimeException.
+ } catch (IllegalStateException e) {
Slog.w(TAG, "Exception while stopping BLE scanning", e);
}
+ } else {
+ Slog.w(TAG, "BLE scanning is not turned on");
}
mScanning = false;
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index efb2cb7a3283..2a219289cf10 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -411,8 +411,11 @@ final class LocalDisplayAdapter extends DisplayAdapter {
// For a new display, we need to initialize the default mode ID.
if (mDefaultModeId == INVALID_MODE_ID) {
- mDefaultModeId = activeRecord.mMode.getModeId();
- mDefaultModeGroup = mActiveSfDisplayMode.group;
+ mDefaultModeId = mSystemPreferredModeId != INVALID_MODE_ID
+ ? mSystemPreferredModeId : activeRecord.mMode.getModeId();
+ mDefaultModeGroup = mSystemPreferredModeId != INVALID_MODE_ID
+ ? preferredSfDisplayMode.group
+ : mActiveSfDisplayMode.group;
} else if (modesAdded && activeModeChanged) {
Slog.d(TAG, "New display modes are added and the active mode has changed, "
+ "use active mode as default mode.");
@@ -894,13 +897,6 @@ final class LocalDisplayAdapter extends DisplayAdapter {
public void setUserPreferredDisplayModeLocked(Display.Mode mode) {
final int oldModeId = getPreferredModeId();
mUserPreferredMode = mode;
- // When clearing the user preferred mode we need to also reset the default mode. This is
- // used by DisplayModeDirector to determine the default resolution, so if we don't clear
- // it then the resolution won't reset to what it would've been prior to setting a user
- // preferred display mode.
- if (mode == null && mSystemPreferredModeId != INVALID_MODE_ID) {
- mDefaultModeId = mSystemPreferredModeId;
- }
if (mode != null && (mode.isRefreshRateSet() || mode.isResolutionSet())) {
Display.Mode matchingSupportedMode;
matchingSupportedMode = findMode(mode.getPhysicalWidth(),
diff --git a/services/core/java/com/android/server/wm/AppTransitionController.java b/services/core/java/com/android/server/wm/AppTransitionController.java
index 5599f2cfc374..9c95e31cc5f5 100644
--- a/services/core/java/com/android/server/wm/AppTransitionController.java
+++ b/services/core/java/com/android/server/wm/AppTransitionController.java
@@ -1032,8 +1032,12 @@ public class AppTransitionController {
private void applyAnimations(ArraySet<ActivityRecord> openingApps,
ArraySet<ActivityRecord> closingApps, @TransitionOldType int transit,
LayoutParams animLp, boolean voiceInteraction) {
+ final RecentsAnimationController rac = mService.getRecentsAnimationController();
if (transit == WindowManager.TRANSIT_OLD_UNSET
|| (openingApps.isEmpty() && closingApps.isEmpty())) {
+ if (rac != null) {
+ rac.sendTasksAppeared();
+ }
return;
}
@@ -1071,7 +1075,6 @@ public class AppTransitionController {
voiceInteraction);
applyAnimations(closingWcs, closingApps, transit, false /* visible */, animLp,
voiceInteraction);
- final RecentsAnimationController rac = mService.getRecentsAnimationController();
if (rac != null) {
rac.sendTasksAppeared();
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java b/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java
index ed369c016770..9c615d140e85 100644
--- a/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java
@@ -764,13 +764,11 @@ public class LocalDisplayAdapterTest {
@Test
public void testGetSystemPreferredDisplayMode() throws Exception {
SurfaceControl.DisplayMode displayMode1 = createFakeDisplayMode(0, 1920, 1080, 60f);
- // system preferred mode
+ // preferred mode
SurfaceControl.DisplayMode displayMode2 = createFakeDisplayMode(1, 3840, 2160, 60f);
- // user preferred mode
- SurfaceControl.DisplayMode displayMode3 = createFakeDisplayMode(2, 1920, 1080, 30f);
SurfaceControl.DisplayMode[] modes =
- new SurfaceControl.DisplayMode[]{displayMode1, displayMode2, displayMode3};
+ new SurfaceControl.DisplayMode[]{displayMode1, displayMode2};
FakeDisplay display = new FakeDisplay(PORT_A, modes, 0, 1);
setUpDisplay(display);
updateAvailableDisplays();
@@ -782,43 +780,24 @@ public class LocalDisplayAdapterTest {
DisplayDeviceInfo displayDeviceInfo = mListener.addedDisplays.get(
0).getDisplayDeviceInfoLocked();
- assertThat(displayDeviceInfo.supportedModes.length).isEqualTo(modes.length);
- Display.Mode defaultMode = getModeById(displayDeviceInfo, displayDeviceInfo.defaultModeId);
- assertThat(matches(defaultMode, displayMode1)).isTrue();
- // Set the user preferred display mode
- mListener.addedDisplays.get(0).setUserPreferredDisplayModeLocked(
- new Display.Mode(
- displayMode3.width, displayMode3.height, displayMode3.refreshRate));
- updateAvailableDisplays();
- waitForHandlerToComplete(mHandler, HANDLER_WAIT_MS);
- displayDeviceInfo = mListener.addedDisplays.get(
- 0).getDisplayDeviceInfoLocked();
- defaultMode = getModeById(displayDeviceInfo, displayDeviceInfo.defaultModeId);
- assertThat(matches(defaultMode, displayMode3)).isTrue();
+ assertThat(displayDeviceInfo.supportedModes.length).isEqualTo(modes.length);
- // clear the user preferred mode
- mListener.addedDisplays.get(0).setUserPreferredDisplayModeLocked(null);
- updateAvailableDisplays();
- waitForHandlerToComplete(mHandler, HANDLER_WAIT_MS);
- displayDeviceInfo = mListener.addedDisplays.get(
- 0).getDisplayDeviceInfoLocked();
- defaultMode = getModeById(displayDeviceInfo, displayDeviceInfo.defaultModeId);
+ Display.Mode defaultMode = getModeById(displayDeviceInfo, displayDeviceInfo.defaultModeId);
assertThat(matches(defaultMode, displayMode2)).isTrue();
- // Change the display and add new system preferred mode
- SurfaceControl.DisplayMode addedDisplayInfo = createFakeDisplayMode(3, 2340, 1080, 20f);
- modes = new SurfaceControl.DisplayMode[]{
- displayMode1, displayMode2, displayMode3, addedDisplayInfo};
+ // Change the display and add new preferred mode
+ SurfaceControl.DisplayMode addedDisplayInfo = createFakeDisplayMode(2, 2340, 1080, 60f);
+ modes = new SurfaceControl.DisplayMode[]{displayMode1, displayMode2, addedDisplayInfo};
display.dynamicInfo.supportedDisplayModes = modes;
- display.dynamicInfo.preferredBootDisplayMode = 3;
+ display.dynamicInfo.preferredBootDisplayMode = 2;
setUpDisplay(display);
mInjector.getTransmitter().sendHotplug(display, /* connected */ true);
waitForHandlerToComplete(mHandler, HANDLER_WAIT_MS);
assertTrue(mListener.traversalRequested);
assertThat(mListener.addedDisplays.size()).isEqualTo(1);
- assertThat(mListener.changedDisplays.size()).isEqualTo(3);
+ assertThat(mListener.changedDisplays.size()).isEqualTo(1);
DisplayDevice displayDevice = mListener.changedDisplays.get(0);
displayDevice.applyPendingDisplayDeviceInfoChangesLocked();