diff options
7 files changed, 86 insertions, 27 deletions
diff --git a/core/java/com/android/internal/policy/TransitionAnimation.java b/core/java/com/android/internal/policy/TransitionAnimation.java index faea7706ee14..ece6f2f3571b 100644 --- a/core/java/com/android/internal/policy/TransitionAnimation.java +++ b/core/java/com/android/internal/policy/TransitionAnimation.java @@ -29,7 +29,6 @@ import static android.view.WindowManager.TRANSIT_OLD_WALLPAPER_INTRA_CLOSE; import static android.view.WindowManager.TRANSIT_OLD_WALLPAPER_INTRA_OPEN; import static android.view.WindowManager.TRANSIT_OPEN; -import android.annotation.DrawableRes; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; @@ -915,7 +914,7 @@ public class TransitionAnimation { * animation. */ public HardwareBuffer createCrossProfileAppsThumbnail( - @DrawableRes int thumbnailDrawableRes, Rect frame) { + Drawable thumbnailDrawable, Rect frame) { final int width = frame.width(); final int height = frame.height(); @@ -924,14 +923,13 @@ public class TransitionAnimation { canvas.drawColor(Color.argb(0.6f, 0, 0, 0)); final int thumbnailSize = mContext.getResources().getDimensionPixelSize( com.android.internal.R.dimen.cross_profile_apps_thumbnail_size); - final Drawable drawable = mContext.getDrawable(thumbnailDrawableRes); - drawable.setBounds( + thumbnailDrawable.setBounds( (width - thumbnailSize) / 2, (height - thumbnailSize) / 2, (width + thumbnailSize) / 2, (height + thumbnailSize) / 2); - drawable.setTint(mContext.getColor(android.R.color.white)); - drawable.draw(canvas); + thumbnailDrawable.setTint(mContext.getColor(android.R.color.white)); + thumbnailDrawable.draw(canvas); picture.endRecording(); return Bitmap.createBitmap(picture).getHardwareBuffer(); 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 f61e62444366..9f4ff7c8dc06 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 @@ -471,9 +471,10 @@ public abstract class WMShellBaseModule { static Transitions provideTransitions(ShellTaskOrganizer organizer, TransactionPool pool, DisplayController displayController, Context context, @ShellMainThread ShellExecutor mainExecutor, + @ShellMainThread Handler mainHandler, @ShellAnimationThread ShellExecutor animExecutor) { return new Transitions(organizer, pool, displayController, context, mainExecutor, - animExecutor); + mainHandler, animExecutor); } @WMSingleton 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 79c8a87acb5b..27b6dc5b304f 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 @@ -25,6 +25,11 @@ 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.WINDOWING_MODE_PINNED; +import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_RESOURCE_UPDATED; +import static android.app.admin.DevicePolicyManager.EXTRA_RESOURCE_TYPE_DRAWABLE; +import static android.app.admin.DevicePolicyResources.Drawables.Source.PROFILE_SWITCH_ANIMATION; +import static android.app.admin.DevicePolicyResources.Drawables.Style.OUTLINE; +import static android.app.admin.DevicePolicyResources.Drawables.WORK_PROFILE_ICON; import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_JUMPCUT; import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_ROTATE; import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS; @@ -57,11 +62,17 @@ import android.annotation.ColorInt; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityThread; +import android.app.admin.DevicePolicyManager; +import android.content.BroadcastReceiver; import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; import android.graphics.Color; import android.graphics.Point; import android.graphics.Rect; +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; @@ -118,6 +129,7 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { private final ShellExecutor mMainExecutor; private final ShellExecutor mAnimExecutor; private final TransitionAnimation mTransitionAnimation; + private final DevicePolicyManager mDevicePolicyManager; private final SurfaceSession mSurfaceSession = new SurfaceSession(); @@ -132,9 +144,24 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { private ScreenRotationAnimation mRotationAnimation; + private Drawable mEnterpriseThumbnailDrawable; + + private BroadcastReceiver mEnterpriseResourceUpdatedReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + boolean isDrawable = intent.getBooleanExtra( + EXTRA_RESOURCE_TYPE_DRAWABLE, /* default= */ false); + if (!isDrawable) { + return; + } + updateEnterpriseThumbnailDrawable(); + } + }; + DefaultTransitionHandler(@NonNull DisplayController displayController, @NonNull TransactionPool transactionPool, Context context, - @NonNull ShellExecutor mainExecutor, @NonNull ShellExecutor animExecutor) { + @NonNull ShellExecutor mainExecutor, @NonNull Handler mainHandler, + @NonNull ShellExecutor animExecutor) { mDisplayController = displayController; mTransactionPool = transactionPool; mContext = context; @@ -143,9 +170,23 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { mTransitionAnimation = new TransitionAnimation(context, false /* debug */, Transitions.TAG); mCurrentUserId = UserHandle.myUserId(); + mDevicePolicyManager = context.getSystemService(DevicePolicyManager.class); + updateEnterpriseThumbnailDrawable(); + mContext.registerReceiver( + mEnterpriseResourceUpdatedReceiver, + new IntentFilter(ACTION_DEVICE_POLICY_RESOURCE_UPDATED), + /* broadcastPermission = */ null, + mainHandler); + AttributeCache.init(context); } + private void updateEnterpriseThumbnailDrawable() { + mEnterpriseThumbnailDrawable = mDevicePolicyManager.getDrawable( + WORK_PROFILE_ICON, OUTLINE, PROFILE_SWITCH_ANIMATION, + () -> mContext.getDrawable(R.drawable.ic_corp_badge)); + } + @VisibleForTesting static boolean isRotationSeamless(@NonNull TransitionInfo info, DisplayController displayController) { @@ -632,7 +673,7 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { final boolean isClose = Transitions.isClosingType(change.getMode()); if (isOpen) { if (options.getType() == ANIM_OPEN_CROSS_PROFILE_APPS && isTask) { - attachCrossProfileThunmbnailAnimation(animations, finishCallback, change, + attachCrossProfileThumbnailAnimation(animations, finishCallback, change, cornerRadius); } else if (options.getType() == ANIM_THUMBNAIL_SCALE_UP) { attachThumbnailAnimation(animations, finishCallback, change, options, cornerRadius); @@ -642,13 +683,14 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { } } - private void attachCrossProfileThunmbnailAnimation(@NonNull ArrayList<Animator> animations, + private void attachCrossProfileThumbnailAnimation(@NonNull ArrayList<Animator> animations, @NonNull Runnable finishCallback, TransitionInfo.Change change, float cornerRadius) { - final int thumbnailDrawableRes = change.getTaskInfo().userId == mCurrentUserId - ? R.drawable.ic_account_circle : R.drawable.ic_corp_badge; final Rect bounds = change.getEndAbsBounds(); + // Show the right drawable depending on the user we're transitioning to. + final Drawable thumbnailDrawable = change.getTaskInfo().userId == mCurrentUserId + ? mContext.getDrawable(R.drawable.ic_account_circle) : mEnterpriseThumbnailDrawable; final HardwareBuffer thumbnail = mTransitionAnimation.createCrossProfileAppsThumbnail( - thumbnailDrawableRes, bounds); + thumbnailDrawable, bounds); if (thumbnail == null) { return; } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java index 33a98b2fd80e..86b73fc30ca8 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java @@ -33,6 +33,7 @@ import android.annotation.Nullable; import android.content.ContentResolver; import android.content.Context; import android.database.ContentObserver; +import android.os.Handler; import android.os.IBinder; import android.os.RemoteException; import android.os.SystemProperties; @@ -123,7 +124,8 @@ public class Transitions implements RemoteCallable<Transitions> { public Transitions(@NonNull WindowOrganizer organizer, @NonNull TransactionPool pool, @NonNull DisplayController displayController, @NonNull Context context, - @NonNull ShellExecutor mainExecutor, @NonNull ShellExecutor animExecutor) { + @NonNull ShellExecutor mainExecutor, @NonNull Handler mainHandler, + @NonNull ShellExecutor animExecutor) { mOrganizer = organizer; mContext = context; mMainExecutor = mainExecutor; @@ -132,7 +134,7 @@ public class Transitions implements RemoteCallable<Transitions> { mPlayerImpl = new TransitionPlayerImpl(); // The very last handler (0 in the list) should be the default one. mHandlers.add(new DefaultTransitionHandler(displayController, pool, context, mainExecutor, - animExecutor)); + mainHandler, animExecutor)); // Next lowest priority is remote transitions. mRemoteTransitionHandler = new RemoteTransitionHandler(mainExecutor); mHandlers.add(mRemoteTransitionHandler); diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java index e39171343bb9..0f4a06f22986 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java @@ -54,7 +54,9 @@ import static org.mockito.Mockito.verify; import android.app.ActivityManager.RunningTaskInfo; import android.content.Context; import android.os.Binder; +import android.os.Handler; import android.os.IBinder; +import android.os.Looper; import android.os.RemoteException; import android.view.IDisplayWindowListener; import android.view.IWindowManager; @@ -84,8 +86,6 @@ import com.android.wm.shell.common.TransactionPool; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; import java.util.ArrayList; @@ -106,6 +106,7 @@ public class ShellTransitionTests { private final TestShellExecutor mMainExecutor = new TestShellExecutor(); private final ShellExecutor mAnimExecutor = new TestShellExecutor(); private final TestTransitionHandler mDefaultHandler = new TestTransitionHandler(); + private final Handler mMainHandler = new Handler(Looper.getMainLooper()); @Before public void setUp() { @@ -752,7 +753,7 @@ public class ShellTransitionTests { private Transitions createTestTransitions() { return new Transitions(mOrganizer, mTransactionPool, createTestDisplayController(), - mContext, mMainExecutor, mAnimExecutor); + mContext, mMainExecutor, mMainHandler, mAnimExecutor); } // // private class TestDisplayController extends DisplayController { diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 3fe616660284..5f04b7e2621a 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -46,6 +46,9 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.activityTypeToString; import static android.app.WindowConfiguration.isSplitScreenWindowingMode; +import static android.app.admin.DevicePolicyResources.Drawables.Source.PROFILE_SWITCH_ANIMATION; +import static android.app.admin.DevicePolicyResources.Drawables.Style.OUTLINE; +import static android.app.admin.DevicePolicyResources.Drawables.WORK_PROFILE_ICON; import static android.content.Intent.ACTION_MAIN; import static android.content.Intent.CATEGORY_HOME; import static android.content.Intent.CATEGORY_LAUNCHER; @@ -241,6 +244,7 @@ import android.app.TaskInfo; import android.app.TaskInfo.CameraCompatControlState; import android.app.WaitResult; import android.app.WindowConfiguration; +import android.app.admin.DevicePolicyManager; import android.app.servertransaction.ActivityConfigurationChangeItem; import android.app.servertransaction.ActivityLifecycleItem; import android.app.servertransaction.ActivityRelaunchItem; @@ -272,6 +276,7 @@ import android.graphics.Bitmap; import android.graphics.PixelFormat; import android.graphics.Point; import android.graphics.Rect; +import android.graphics.drawable.Drawable; import android.hardware.HardwareBuffer; import android.net.Uri; import android.os.Binder; @@ -538,6 +543,15 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // Tracking splash screen status from previous activity boolean mSplashScreenStyleEmpty = false; + Drawable mEnterpriseThumbnailDrawable; + + private void updateEnterpriseThumbnailDrawable(Context context) { + DevicePolicyManager dpm = context.getSystemService(DevicePolicyManager.class); + mEnterpriseThumbnailDrawable = dpm.getDrawable( + WORK_PROFILE_ICON, OUTLINE, PROFILE_SWITCH_ANIMATION, + () -> context.getDrawable(R.drawable.ic_corp_badge)); + } + static final int LAUNCH_SOURCE_TYPE_SYSTEM = 1; static final int LAUNCH_SOURCE_TYPE_HOME = 2; static final int LAUNCH_SOURCE_TYPE_SYSTEMUI = 3; @@ -1930,6 +1944,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A mAtmService.mPackageConfigPersister.updateConfigIfNeeded(this, mUserId, packageName); mActivityRecordInputSink = new ActivityRecordInputSink(this); + + updateEnterpriseThumbnailDrawable(mAtmService.mUiContext); } /** @@ -6993,12 +7009,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A return; } final Rect frame = win.getRelativeFrame(); - final int thumbnailDrawableRes = task.mUserId == mWmService.mCurrentUserId - ? R.drawable.ic_account_circle - : R.drawable.ic_corp_badge; - final HardwareBuffer thumbnail = - getDisplayContent().mAppTransition - .createCrossProfileAppsThumbnail(thumbnailDrawableRes, frame); + final Drawable thumbnailDrawable = task.mUserId == mWmService.mCurrentUserId + ? mAtmService.mUiContext.getDrawable(R.drawable.ic_account_circle) + : mEnterpriseThumbnailDrawable; + final HardwareBuffer thumbnail = getDisplayContent().mAppTransition + .createCrossProfileAppsThumbnail(thumbnailDrawable, frame); if (thumbnail == null) { return; } diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java index d5abe4f8ed02..56adcfd76403 100644 --- a/services/core/java/com/android/server/wm/AppTransition.java +++ b/services/core/java/com/android/server/wm/AppTransition.java @@ -93,7 +93,6 @@ import static com.android.server.wm.WindowManagerInternal.KeyguardExitAnimationS import static com.android.server.wm.WindowStateAnimator.ROOT_TASK_CLIP_AFTER_ANIM; import static com.android.server.wm.WindowStateAnimator.ROOT_TASK_CLIP_NONE; -import android.annotation.DrawableRes; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.ComponentName; @@ -101,6 +100,7 @@ import android.content.Context; import android.content.res.Configuration; import android.content.res.TypedArray; import android.graphics.Rect; +import android.graphics.drawable.Drawable; import android.hardware.HardwareBuffer; import android.os.Binder; import android.os.Debug; @@ -539,8 +539,8 @@ public class AppTransition implements Dump { * animation. */ HardwareBuffer createCrossProfileAppsThumbnail( - @DrawableRes int thumbnailDrawableRes, Rect frame) { - return mTransitionAnimation.createCrossProfileAppsThumbnail(thumbnailDrawableRes, frame); + Drawable thumbnailDrawable, Rect frame) { + return mTransitionAnimation.createCrossProfileAppsThumbnail(thumbnailDrawable, frame); } Animation createCrossProfileAppsThumbnailAnimationLocked(Rect appRect) { |