diff --git a/core/java/android/app/ActivityClient.java b/core/java/android/app/ActivityClient.java index d465b220f8546..401f8cc13bad8 100644 --- a/core/java/android/app/ActivityClient.java +++ b/core/java/android/app/ActivityClient.java @@ -26,6 +26,8 @@ import android.os.RemoteException; import android.util.Singleton; import android.view.RemoteAnimationDefinition; +import com.android.internal.policy.IKeyguardDismissCallback; + /** * Provides the activity associated operations that communicate with system. * @@ -431,6 +433,37 @@ public class ActivityClient { } } + /** + * Restart the process and activity to adopt the latest configuration for size compat mode. + * This only takes effect for visible activity because invisible background activity can be + * restarted naturally when it becomes visible. + */ + public void restartActivityProcessIfVisible(IBinder token) { + try { + getActivityClientController().restartActivityProcessIfVisible(token); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + + /** Removes the snapshot of home task. */ + public void invalidateHomeTaskSnapshot(IBinder homeToken) { + try { + getActivityClientController().invalidateHomeTaskSnapshot(homeToken); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + + void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback, + CharSequence message) { + try { + getActivityClientController().dismissKeyguard(token, callback, message); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition) { try { getActivityClientController().registerRemoteAnimations(token, definition); diff --git a/core/java/android/app/IActivityClientController.aidl b/core/java/android/app/IActivityClientController.aidl index ebf1027382c59..9127ebb4eb837 100644 --- a/core/java/android/app/IActivityClientController.aidl +++ b/core/java/android/app/IActivityClientController.aidl @@ -25,6 +25,8 @@ import android.os.Bundle; import android.os.PersistableBundle; import android.view.RemoteAnimationDefinition; +import com.android.internal.policy.IKeyguardDismissCallback; + /** * Interface for the callback and request from an activity to system. * @@ -95,6 +97,27 @@ interface IActivityClientController { /** See {@link android.app.Activity#setDisablePreviewScreenshots}. */ oneway void setDisablePreviewScreenshots(in IBinder token, boolean disable); + /** + * Restarts the activity by killing its process if it is visible. If the activity is not + * visible, the activity will not be restarted immediately and just keep the activity record in + * the stack. It also resets the current override configuration so the activity will use the + * configuration according to the latest state. + * + * @param activityToken The token of the target activity to restart. + */ + void restartActivityProcessIfVisible(in IBinder activityToken); + + /** + * It should only be called from home activity to remove its outdated snapshot. The home + * snapshot is used to speed up entering home from screen off. If the content of home activity + * is significantly different from before taking the snapshot, then the home activity can use + * this method to avoid inconsistent transition. + */ + void invalidateHomeTaskSnapshot(IBinder homeToken); + + void dismissKeyguard(in IBinder token, in IKeyguardDismissCallback callback, + in CharSequence message); + /** Registers remote animations for a specific activity. */ void registerRemoteAnimations(in IBinder token, in RemoteAnimationDefinition definition); diff --git a/core/java/android/app/IActivityTaskManager.aidl b/core/java/android/app/IActivityTaskManager.aidl index b0853404a0aa6..38a3e70b37426 100644 --- a/core/java/android/app/IActivityTaskManager.aidl +++ b/core/java/android/app/IActivityTaskManager.aidl @@ -72,7 +72,6 @@ import android.view.RemoteAnimationAdapter; import android.window.IWindowOrganizerController; import com.android.internal.app.IVoiceInteractor; import com.android.internal.os.IResultReceiver; -import com.android.internal.policy.IKeyguardDismissCallback; import java.util.List; @@ -85,8 +84,6 @@ import java.util.List; // TODO(b/174040395): Make this interface private to ActivityTaskManager.java and have external // caller go through that call instead. This would help us better separate and control the API // surface exposed. -// TODO(b/174041144): Move callback methods from Activity (Things that take param 'IBinder token') -// to a separate interface that is only available to the Activity. // TODO(b/174041603): Create a builder interface for things like startActivityXXX(...) to reduce // interface duplication. // TODO(b/174040691): Clean-up/remove all obsolete or unused interfaces like things that should be @@ -294,9 +291,6 @@ interface IActivityTaskManager { // Get device configuration ConfigurationInfo getDeviceConfigurationInfo(); - void dismissKeyguard(in IBinder token, in IKeyguardDismissCallback callback, - in CharSequence message); - /** Cancels the window transitions for the given task. */ void cancelTaskWindowTransition(int taskId); @@ -308,14 +302,6 @@ interface IActivityTaskManager { */ android.window.TaskSnapshot getTaskSnapshot(int taskId, boolean isLowResolution); - /** - * It should only be called from home activity to remove its outdated snapshot. The home - * snapshot is used to speed up entering home from screen off. If the content of home activity - * is significantly different from before taking the snapshot, then the home activity can use - * this method to avoid inconsistent transition. - */ - void invalidateHomeTaskSnapshot(IBinder homeToken); - /** * Return the user id of last resumed activity. */ @@ -362,14 +348,4 @@ interface IActivityTaskManager { * Clears launch params for given packages. */ void clearLaunchParamsForPackages(in List packageNames); - - /** - * Restarts the activity by killing its process if it is visible. If the activity is not - * visible, the activity will not be restarted immediately and just keep the activity record in - * the stack. It also resets the current override configuration so the activity will use the - * configuration according to the latest state. - * - * @param activityToken The token of the target activity to restart. - */ - void restartActivityProcessIfVisible(in IBinder activityToken); } diff --git a/core/java/android/app/KeyguardManager.java b/core/java/android/app/KeyguardManager.java index 545c3f70d4661..b6d25cfb26cea 100644 --- a/core/java/android/app/KeyguardManager.java +++ b/core/java/android/app/KeyguardManager.java @@ -598,33 +598,29 @@ public class KeyguardManager { @SystemApi public void requestDismissKeyguard(@NonNull Activity activity, @Nullable CharSequence message, @Nullable KeyguardDismissCallback callback) { - try { - ActivityTaskManager.getService().dismissKeyguard( - activity.getActivityToken(), new IKeyguardDismissCallback.Stub() { - @Override - public void onDismissError() throws RemoteException { - if (callback != null && !activity.isDestroyed()) { - activity.mHandler.post(callback::onDismissError); - } + ActivityClient.getInstance().dismissKeyguard( + activity.getActivityToken(), new IKeyguardDismissCallback.Stub() { + @Override + public void onDismissError() throws RemoteException { + if (callback != null && !activity.isDestroyed()) { + activity.mHandler.post(callback::onDismissError); } + } - @Override - public void onDismissSucceeded() throws RemoteException { - if (callback != null && !activity.isDestroyed()) { - activity.mHandler.post(callback::onDismissSucceeded); - } + @Override + public void onDismissSucceeded() throws RemoteException { + if (callback != null && !activity.isDestroyed()) { + activity.mHandler.post(callback::onDismissSucceeded); } + } - @Override - public void onDismissCancelled() throws RemoteException { - if (callback != null && !activity.isDestroyed()) { - activity.mHandler.post(callback::onDismissCancelled); - } + @Override + public void onDismissCancelled() throws RemoteException { + if (callback != null && !activity.isDestroyed()) { + activity.mHandler.post(callback::onDismissCancelled); } - }, message); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } + } + }, message); } /** diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java index e5c4bf32db3a2..9164137feb418 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java @@ -24,6 +24,7 @@ import static android.app.ActivityTaskManager.getService; import android.annotation.NonNull; import android.app.Activity; +import android.app.ActivityClient; import android.app.ActivityManager; import android.app.ActivityManager.RecentTaskInfo; import android.app.ActivityManager.RunningTaskInfo; @@ -140,8 +141,9 @@ public class ActivityManagerWrapper { */ public void invalidateHomeTaskSnapshot(final Activity homeActivity) { try { - getService().invalidateHomeTaskSnapshot(homeActivity.getActivityToken()); - } catch (RemoteException e) { + ActivityClient.getInstance().invalidateHomeTaskSnapshot( + homeActivity.getActivityToken()); + } catch (Throwable e) { Log.w(TAG, "Failed to invalidate home snapshot", e); } } diff --git a/packages/SystemUI/src/com/android/systemui/SizeCompatModeActivityController.java b/packages/SystemUI/src/com/android/systemui/SizeCompatModeActivityController.java index 02f34ac3dec00..5384ddfd18bf6 100644 --- a/packages/SystemUI/src/com/android/systemui/SizeCompatModeActivityController.java +++ b/packages/SystemUI/src/com/android/systemui/SizeCompatModeActivityController.java @@ -16,7 +16,7 @@ package com.android.systemui; -import android.app.ActivityTaskManager; +import android.app.ActivityClient; import android.content.Context; import android.content.res.ColorStateList; import android.graphics.Color; @@ -27,7 +27,6 @@ import android.graphics.drawable.RippleDrawable; import android.hardware.display.DisplayManager; import android.inputmethodservice.InputMethodService; import android.os.IBinder; -import android.os.RemoteException; import android.util.Log; import android.util.SparseArray; import android.view.Display; @@ -237,12 +236,7 @@ public class SizeCompatModeActivityController extends SystemUI implements Comman @Override public void onClick(View v) { - try { - ActivityTaskManager.getService().restartActivityProcessIfVisible( - mLastActivityToken); - } catch (RemoteException e) { - Log.w(TAG, "Unable to restart activity", e); - } + ActivityClient.getInstance().restartActivityProcessIfVisible(mLastActivityToken); } @Override diff --git a/services/core/java/com/android/server/wm/ActivityClientController.java b/services/core/java/com/android/server/wm/ActivityClientController.java index c25f1b419e662..5fe853a38dd7f 100644 --- a/services/core/java/com/android/server/wm/ActivityClientController.java +++ b/services/core/java/com/android/server/wm/ActivityClientController.java @@ -63,6 +63,7 @@ import android.util.Slog; import android.view.RemoteAnimationDefinition; import com.android.internal.app.AssistUtils; +import com.android.internal.policy.IKeyguardDismissCallback; import com.android.internal.protolog.common.ProtoLog; import com.android.server.LocalServices; import com.android.server.Watchdog; @@ -1018,6 +1019,50 @@ class ActivityClientController extends IActivityClientController.Stub { } } + @Override + public void restartActivityProcessIfVisible(IBinder token) { + ActivityTaskManagerService.enforceTaskPermission("restartActivityProcess"); + final long callingId = Binder.clearCallingIdentity(); + try { + synchronized (mGlobalLock) { + final ActivityRecord r = ActivityRecord.isInRootTaskLocked(token); + if (r != null) { + r.restartProcessIfVisible(); + } + } + } finally { + Binder.restoreCallingIdentity(callingId); + } + } + + @Override + public void invalidateHomeTaskSnapshot(IBinder token) { + synchronized (mGlobalLock) { + final ActivityRecord r = ActivityRecord.isInRootTaskLocked(token); + if (r != null && r.isActivityTypeHome()) { + mService.mWindowManager.mTaskSnapshotController.removeSnapshotCache( + r.getTask().mTaskId); + } + } + } + + @Override + public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback, + CharSequence message) { + if (message != null) { + mService.mAmInternal.enforceCallingPermission( + android.Manifest.permission.SHOW_KEYGUARD_MESSAGE, "dismissKeyguard"); + } + final long callingId = Binder.clearCallingIdentity(); + try { + synchronized (mGlobalLock) { + mService.mKeyguardController.dismissKeyguard(token, callback, message); + } + } finally { + Binder.restoreCallingIdentity(callingId); + } + } + @Override public void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition) { mService.mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS, diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index 56105737bb822..f0db3f9855dfb 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -231,7 +231,6 @@ import com.android.internal.app.ProcessMap; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; import com.android.internal.notification.SystemNotificationChannels; import com.android.internal.os.TransferPipe; -import com.android.internal.policy.IKeyguardDismissCallback; import com.android.internal.policy.KeyguardDismissCallback; import com.android.internal.protolog.common.ProtoLog; import com.android.internal.util.ArrayUtils; @@ -1795,23 +1794,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } } - @Override - public void restartActivityProcessIfVisible(IBinder activityToken) { - enforceTaskPermission("restartActivityProcess()"); - final long callingId = Binder.clearCallingIdentity(); - try { - synchronized (mGlobalLock) { - final ActivityRecord r = ActivityRecord.isInRootTaskLocked(activityToken); - if (r == null) { - return; - } - r.restartProcessIfVisible(); - } - } finally { - Binder.restoreCallingIdentity(callingId); - } - } - @Override public boolean removeTask(int taskId) { enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeTask()"); @@ -3263,7 +3245,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { // If the keyguard is showing or occluded, then try and dismiss it before // entering picture-in-picture (this will prompt the user to authenticate if the // device is currently locked). - dismissKeyguard(r.appToken, new KeyguardDismissCallback() { + mActivityClientController.dismissKeyguard(r.appToken, new KeyguardDismissCallback() { @Override public void onDismissSucceeded() { mH.post(enterPipRunnable); @@ -3387,23 +3369,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } } - @Override - public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback, - CharSequence message) { - if (message != null) { - mAmInternal.enforceCallingPermission( - Manifest.permission.SHOW_KEYGUARD_MESSAGE, "dismissKeyguard()"); - } - final long callingId = Binder.clearCallingIdentity(); - try { - synchronized (mGlobalLock) { - mKeyguardController.dismissKeyguard(token, callback, message); - } - } finally { - Binder.restoreCallingIdentity(callingId); - } - } - @Override public void cancelTaskWindowTransition(int taskId) { enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_TASKS, @@ -3450,17 +3415,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { return task.getSnapshot(isLowResolution, restoreFromDisk); } - @Override - public void invalidateHomeTaskSnapshot(IBinder token) { - synchronized (mGlobalLock) { - final ActivityRecord r = ActivityRecord.isInRootTaskLocked(token); - if (r == null || !r.isActivityTypeHome()) { - return; - } - mWindowManager.mTaskSnapshotController.removeSnapshotCache(r.getTask().mTaskId); - } - } - /** Return the user id of the last resumed activity. */ @Override public @UserIdInt diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java index db773241f063e..371e6802ced74 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java @@ -109,7 +109,7 @@ public class SizeCompatTests extends WindowTestsBase { final Rect originalOverrideBounds = new Rect(mActivity.getBounds()); resizeDisplay(mTask.mDisplayContent, 600, 1200); // The visible activity should recompute configuration according to the last parent bounds. - mAtm.restartActivityProcessIfVisible(mActivity.appToken); + mAtm.mActivityClientController.restartActivityProcessIfVisible(mActivity.appToken); assertEquals(Task.ActivityState.RESTARTING_PROCESS, mActivity.getState()); assertNotEquals(originalOverrideBounds, mActivity.getBounds());