diff options
22 files changed, 1843 insertions, 1540 deletions
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index 5ee5597e1984..f92768a28db1 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -963,8 +963,8 @@ public class Activity extends ContextThemeWrapper * @hide */ @Override - public void toggleFreeformWindowingMode() throws RemoteException { - ActivityTaskManager.getService().toggleFreeformWindowingMode(mToken); + public void toggleFreeformWindowingMode() { + ActivityClient.getInstance().toggleFreeformWindowingMode(mToken); } /** @@ -981,11 +981,8 @@ public class Activity extends ContextThemeWrapper @Override public boolean isTaskRoot() { - try { - return ActivityTaskManager.getService().getTaskForActivity(mToken, true) >= 0; - } catch (RemoteException e) { - return false; - } + return ActivityClient.getInstance().getTaskForActivity( + mToken, true /* onlyRoot */) >= 0; } /** @@ -2052,12 +2049,8 @@ public class Activity extends ContextThemeWrapper * {@link #isVoiceInteractionRoot()} return {@code false} in this case. */ public boolean isVoiceInteractionRoot() { - try { - return mVoiceInteractor != null - && ActivityTaskManager.getService().isRootVoiceInteraction(mToken); - } catch (RemoteException e) { - } - return false; + return mVoiceInteractor != null + && ActivityClient.getInstance().isRootVoiceInteraction(mToken); } /** @@ -2090,10 +2083,7 @@ public class Activity extends ContextThemeWrapper * @param privateOptions a Bundle of private arguments to the current voice interaction service */ public void startLocalVoiceInteraction(Bundle privateOptions) { - try { - ActivityTaskManager.getService().startLocalVoiceInteraction(mToken, privateOptions); - } catch (RemoteException re) { - } + ActivityClient.getInstance().startLocalVoiceInteraction(mToken, privateOptions); } /** @@ -2119,10 +2109,7 @@ public class Activity extends ContextThemeWrapper * terminated, {@link #onLocalVoiceInteractionStopped()} will be called. */ public void stopLocalVoiceInteraction() { - try { - ActivityTaskManager.getService().stopLocalVoiceInteraction(mToken); - } catch (RemoteException re) { - } + ActivityClient.getInstance().stopLocalVoiceInteraction(mToken); } /** @@ -2564,11 +2551,7 @@ public class Activity extends ContextThemeWrapper * false will be returned if the caller is not the current top activity. */ public boolean showAssist(Bundle args) { - try { - return ActivityTaskManager.getService().showAssistFromActivity(mToken, args); - } catch (RemoteException e) { - } - return false; + return ActivityClient.getInstance().showAssistFromActivity(mToken, args); } /** @@ -2708,10 +2691,9 @@ public class Activity extends ContextThemeWrapper } mDoReportFullyDrawn = false; try { - ActivityTaskManager.getService().reportActivityFullyDrawn( + ActivityClient.getInstance().reportActivityFullyDrawn( mToken, mRestoredFromBundle); VMRuntime.getRuntime().notifyStartupCompleted(); - } catch (RemoteException e) { } finally { Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } @@ -2841,27 +2823,23 @@ public class Activity extends ContextThemeWrapper * does not support picture-in-picture, return false. */ public boolean enterPictureInPictureMode(@NonNull PictureInPictureParams params) { - try { - if (!deviceSupportsPictureInPictureMode()) { - return false; - } - if (params == null) { - throw new IllegalArgumentException("Expected non-null picture-in-picture params"); - } - if (!mCanEnterPictureInPicture) { - throw new IllegalStateException("Activity must be resumed to enter" - + " picture-in-picture"); - } - // Set mIsInPictureInPictureMode earlier and don't wait for - // onPictureInPictureModeChanged callback here. This is to ensure that - // isInPictureInPictureMode returns true in the following onPause callback. - // See https://developer.android.com/guide/topics/ui/picture-in-picture for guidance. - mIsInPictureInPictureMode = ActivityTaskManager.getService().enterPictureInPictureMode( - mToken, params); - return mIsInPictureInPictureMode; - } catch (RemoteException e) { + if (!deviceSupportsPictureInPictureMode()) { return false; } + if (params == null) { + throw new IllegalArgumentException("Expected non-null picture-in-picture params"); + } + if (!mCanEnterPictureInPicture) { + throw new IllegalStateException("Activity must be resumed to enter" + + " picture-in-picture"); + } + // Set mIsInPictureInPictureMode earlier and don't wait for + // onPictureInPictureModeChanged callback here. This is to ensure that + // isInPictureInPictureMode returns true in the following onPause callback. + // See https://developer.android.com/guide/topics/ui/picture-in-picture for guidance. + mIsInPictureInPictureMode = ActivityClient.getInstance().enterPictureInPictureMode( + mToken, params); + return mIsInPictureInPictureMode; } /** @@ -2871,16 +2849,13 @@ public class Activity extends ContextThemeWrapper * @param params the new parameters for the picture-in-picture. */ public void setPictureInPictureParams(@NonNull PictureInPictureParams params) { - try { - if (!deviceSupportsPictureInPictureMode()) { - return; - } - if (params == null) { - throw new IllegalArgumentException("Expected non-null picture-in-picture params"); - } - ActivityTaskManager.getService().setPictureInPictureParams(mToken, params); - } catch (RemoteException e) { + if (!deviceSupportsPictureInPictureMode()) { + return; } + if (params == null) { + throw new IllegalArgumentException("Expected non-null picture-in-picture params"); + } + ActivityClient.getInstance().setPictureInPictureParams(mToken, params); } /** @@ -3822,14 +3797,10 @@ public class Activity extends ContextThemeWrapper finishAfterTransition(); return; } - try { - // Inform activity task manager that the activity received a back press - // while at the root of the task. This call allows ActivityTaskManager - // to intercept or move the task to the back. - ActivityTaskManager.getService().onBackPressedOnTaskRoot(mToken); - } catch (RemoteException e) { - finishAfterTransition(); - } + // Inform activity task manager that the activity received a back press while at the + // root of the task. This call allows ActivityTaskManager to intercept or move the task + // to the back. + ActivityClient.getInstance().onBackPressedOnTaskRoot(mToken); // Activity was launched when user tapped a link in the Autofill Save UI - Save UI must // be restored now. @@ -6114,11 +6085,8 @@ public class Activity extends ContextThemeWrapper * the outgoing activity. Use 0 for no animation. */ public void overridePendingTransition(int enterAnim, int exitAnim) { - try { - ActivityTaskManager.getService().overridePendingTransition( - mToken, getPackageName(), enterAnim, exitAnim); - } catch (RemoteException e) { - } + ActivityClient.getInstance().overridePendingTransition(mToken, getPackageName(), + enterAnim, exitAnim); } /** @@ -6239,11 +6207,7 @@ public class Activity extends ContextThemeWrapper */ @Nullable public String getCallingPackage() { - try { - return ActivityTaskManager.getService().getCallingPackage(mToken); - } catch (RemoteException e) { - return null; - } + return ActivityClient.getInstance().getCallingPackage(mToken); } /** @@ -6262,11 +6226,7 @@ public class Activity extends ContextThemeWrapper */ @Nullable public ComponentName getCallingActivity() { - try { - return ActivityTaskManager.getService().getCallingActivity(mToken); - } catch (RemoteException e) { - return null; - } + return ActivityClient.getInstance().getCallingActivity(mToken); } /** @@ -6364,16 +6324,12 @@ public class Activity extends ContextThemeWrapper resultData = mResultData; } if (false) Log.v(TAG, "Finishing self: token=" + mToken); - try { - if (resultData != null) { - resultData.prepareToLeaveProcess(this); - } - if (ActivityTaskManager.getService() - .finishActivity(mToken, resultCode, resultData, finishTask)) { - mFinished = true; - } - } catch (RemoteException e) { - // Empty + if (resultData != null) { + resultData.prepareToLeaveProcess(this); + } + if (ActivityClient.getInstance().finishActivity(mToken, resultCode, resultData, + finishTask)) { + mFinished = true; } } else { mParent.finishFromChild(this); @@ -6429,12 +6385,8 @@ public class Activity extends ContextThemeWrapper if (mResultCode != RESULT_CANCELED || mResultData != null) { throw new IllegalStateException("Can not be called to deliver a result"); } - try { - if (ActivityTaskManager.getService().finishActivityAffinity(mToken)) { - mFinished = true; - } - } catch (RemoteException e) { - // Empty + if (ActivityClient.getInstance().finishActivityAffinity(mToken)) { + mFinished = true; } } @@ -6477,12 +6429,7 @@ public class Activity extends ContextThemeWrapper */ public void finishActivity(int requestCode) { if (mParent == null) { - try { - ActivityTaskManager.getService() - .finishSubActivity(mToken, mEmbeddedID, requestCode); - } catch (RemoteException e) { - // Empty - } + ActivityClient.getInstance().finishSubActivity(mToken, mEmbeddedID, requestCode); } else { mParent.finishActivityFromChild(this, requestCode); } @@ -6499,12 +6446,7 @@ public class Activity extends ContextThemeWrapper */ @Deprecated public void finishActivityFromChild(@NonNull Activity child, int requestCode) { - try { - ActivityTaskManager.getService() - .finishSubActivity(mToken, child.mEmbeddedID, requestCode); - } catch (RemoteException e) { - // Empty - } + ActivityClient.getInstance().finishSubActivity(mToken, child.mEmbeddedID, requestCode); } /** @@ -6527,12 +6469,7 @@ public class Activity extends ContextThemeWrapper * being finished, it hasn't yet saved its state, etc. */ public boolean releaseInstance() { - try { - return ActivityTaskManager.getService().releaseActivityInstance(mToken); - } catch (RemoteException e) { - // Empty - } - return false; + return ActivityClient.getInstance().releaseActivityInstance(mToken); } /** @@ -6644,12 +6581,7 @@ public class Activity extends ContextThemeWrapper */ public void setRequestedOrientation(@ActivityInfo.ScreenOrientation int requestedOrientation) { if (mParent == null) { - try { - ActivityTaskManager.getService().setRequestedOrientation( - mToken, requestedOrientation); - } catch (RemoteException e) { - // Empty - } + ActivityClient.getInstance().setRequestedOrientation(mToken, requestedOrientation); } else { mParent.setRequestedOrientation(requestedOrientation); } @@ -6667,16 +6599,10 @@ public class Activity extends ContextThemeWrapper @ActivityInfo.ScreenOrientation public int getRequestedOrientation() { if (mParent == null) { - try { - return ActivityTaskManager.getService() - .getRequestedOrientation(mToken); - } catch (RemoteException e) { - // Empty - } + return ActivityClient.getInstance().getRequestedOrientation(mToken); } else { return mParent.getRequestedOrientation(); } - return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; } /** @@ -6686,11 +6612,7 @@ public class Activity extends ContextThemeWrapper * @return Task identifier, an opaque integer. */ public int getTaskId() { - try { - return ActivityTaskManager.getService().getTaskForActivity(mToken, false); - } catch (RemoteException e) { - return -1; - } + return ActivityClient.getInstance().getTaskForActivity(mToken, false /* onlyRoot */); } /** @@ -6715,12 +6637,7 @@ public class Activity extends ContextThemeWrapper * back) true is returned, else false. */ public boolean moveTaskToBack(boolean nonRoot) { - try { - return ActivityTaskManager.getService().moveActivityTaskToBack(mToken, nonRoot); - } catch (RemoteException e) { - // Empty - } - return false; + return ActivityClient.getInstance().moveActivityTaskToBack(mToken, nonRoot); } /** @@ -6896,10 +6813,7 @@ public class Activity extends ContextThemeWrapper mTaskDescription.setIcon(Icon.createWithBitmap(icon)); } } - try { - ActivityTaskManager.getService().setTaskDescription(mToken, mTaskDescription); - } catch (RemoteException e) { - } + ActivityClient.getInstance().setTaskDescription(mToken, mTaskDescription); } /** @@ -7210,11 +7124,7 @@ public class Activity extends ContextThemeWrapper * @see android.content.pm.ActivityInfo#FLAG_IMMERSIVE */ public boolean isImmersive() { - try { - return ActivityTaskManager.getService().isImmersive(mToken); - } catch (RemoteException e) { - return false; - } + return ActivityClient.getInstance().isImmersive(mToken); } /** @@ -7228,11 +7138,7 @@ public class Activity extends ContextThemeWrapper if (mToken == null || mWindow == null) { return false; } - try { - return ActivityTaskManager.getService().isTopOfTask(getActivityToken()); - } catch (RemoteException e) { - return false; - } + return ActivityClient.getInstance().isTopOfTask(getActivityToken()); } /** @@ -7271,14 +7177,10 @@ public class Activity extends ContextThemeWrapper } private boolean convertFromTranslucentInternal() { - try { - mTranslucentCallback = null; - if (ActivityTaskManager.getService().convertFromTranslucent(mToken)) { - WindowManagerGlobal.getInstance().changeCanvasOpacity(mToken, true); - return true; - } - } catch (RemoteException e) { - // pass + mTranslucentCallback = null; + if (ActivityClient.getInstance().convertFromTranslucent(mToken)) { + WindowManagerGlobal.getInstance().changeCanvasOpacity(mToken, true /* opaque */); + return true; } return false; } @@ -7307,21 +7209,14 @@ public class Activity extends ContextThemeWrapper @SystemApi public boolean convertToTranslucent(TranslucentConversionListener callback, ActivityOptions options) { - boolean drawComplete; - try { - mTranslucentCallback = callback; - mChangeCanvasToTranslucent = ActivityTaskManager.getService().convertToTranslucent( - mToken, options == null ? null : options.toBundle()); - WindowManagerGlobal.getInstance().changeCanvasOpacity(mToken, false); - drawComplete = true; - } catch (RemoteException e) { - // Make callback return as though it timed out. - mChangeCanvasToTranslucent = false; - drawComplete = false; - } + mTranslucentCallback = callback; + mChangeCanvasToTranslucent = ActivityClient.getInstance().convertToTranslucent( + mToken, options == null ? null : options.toBundle()); + WindowManagerGlobal.getInstance().changeCanvasOpacity(mToken, false); + if (!mChangeCanvasToTranslucent && mTranslucentCallback != null) { // Window is already translucent. - mTranslucentCallback.onTranslucentConversionComplete(drawComplete); + mTranslucentCallback.onTranslucentConversionComplete(true /* drawComplete */); } return mChangeCanvasToTranslucent; } @@ -7355,12 +7250,7 @@ public class Activity extends ContextThemeWrapper */ @UnsupportedAppUsage ActivityOptions getActivityOptions() { - try { - return ActivityOptions.fromBundle( - ActivityTaskManager.getService().getActivityOptions(mToken)); - } catch (RemoteException e) { - } - return null; + return ActivityOptions.fromBundle(ActivityClient.getInstance().getActivityOptions(mToken)); } /** @@ -7504,11 +7394,7 @@ public class Activity extends ContextThemeWrapper * @see android.content.pm.ActivityInfo#FLAG_IMMERSIVE */ public void setImmersive(boolean i) { - try { - ActivityTaskManager.getService().setImmersive(mToken, i); - } catch (RemoteException e) { - // pass - } + ActivityClient.getInstance().setImmersive(mToken, i); } /** @@ -7567,14 +7453,8 @@ public class Activity extends ContextThemeWrapper */ public void setVrModeEnabled(boolean enabled, @NonNull ComponentName requestedComponent) throws PackageManager.NameNotFoundException { - try { - if (ActivityTaskManager.getService().setVrMode(mToken, enabled, requestedComponent) - != 0) { - throw new PackageManager.NameNotFoundException( - requestedComponent.flattenToString()); - } - } catch (RemoteException e) { - // pass + if (ActivityClient.getInstance().setVrMode(mToken, enabled, requestedComponent) != 0) { + throw new PackageManager.NameNotFoundException(requestedComponent.flattenToString()); } } @@ -7689,9 +7569,7 @@ public class Activity extends ContextThemeWrapper if (info.taskAffinity == null) { return false; } - return ActivityTaskManager.getService().shouldUpRecreateTask(mToken, info.taskAffinity); - } catch (RemoteException e) { - return false; + return ActivityClient.getInstance().shouldUpRecreateTask(mToken, info.taskAffinity); } catch (NameNotFoundException e) { return false; } @@ -7739,13 +7617,9 @@ public class Activity extends ContextThemeWrapper if (resultData != null) { resultData.prepareToLeaveProcess(this); } - try { - upIntent.prepareToLeaveProcess(this); - return ActivityTaskManager.getService().navigateUpTo(mToken, upIntent, - resultCode, resultData); - } catch (RemoteException e) { - return false; - } + upIntent.prepareToLeaveProcess(this); + return ActivityClient.getInstance().navigateUpTo(mToken, upIntent, resultCode, + resultData); } else { return mParent.navigateUpToFromChild(this, upIntent); } @@ -8361,10 +8235,7 @@ public class Activity extends ContextThemeWrapper * @see android.R.attr#lockTaskMode */ public void startLockTask() { - try { - ActivityTaskManager.getService().startLockTaskModeByToken(mToken); - } catch (RemoteException e) { - } + ActivityClient.getInstance().startLockTaskModeByToken(mToken); } /** @@ -8384,10 +8255,7 @@ public class Activity extends ContextThemeWrapper * @see ActivityManager#getLockTaskModeState() */ public void stopLockTask() { - try { - ActivityTaskManager.getService().stopLockTaskModeByToken(mToken); - } catch (RemoteException e) { - } + ActivityClient.getInstance().stopLockTaskModeByToken(mToken); } /** @@ -8396,10 +8264,7 @@ public class Activity extends ContextThemeWrapper * of this call for the message to be displayed. */ public void showLockTaskEscapeMessage() { - try { - ActivityTaskManager.getService().showLockTaskEscapeMessage(mToken); - } catch (RemoteException e) { - } + ActivityClient.getInstance().showLockTaskEscapeMessage(mToken); } /** @@ -8667,11 +8532,7 @@ public class Activity extends ContextThemeWrapper */ @UnsupportedAppUsage public void setDisablePreviewScreenshots(boolean disable) { - try { - ActivityTaskManager.getService().setDisablePreviewScreenshots(mToken, disable); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } + ActivityClient.getInstance().setDisablePreviewScreenshots(mToken, disable); } /** @@ -8688,11 +8549,7 @@ public class Activity extends ContextThemeWrapper * @see android.R.attr#showWhenLocked */ public void setShowWhenLocked(boolean showWhenLocked) { - try { - ActivityTaskManager.getService().setShowWhenLocked(mToken, showWhenLocked); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } + ActivityClient.getInstance().setShowWhenLocked(mToken, showWhenLocked); } /** @@ -8711,12 +8568,7 @@ public class Activity extends ContextThemeWrapper * @see android.R.attr#inheritShowWhenLocked */ public void setInheritShowWhenLocked(boolean inheritShowWhenLocked) { - try { - ActivityTaskManager.getService().setInheritShowWhenLocked( - mToken, inheritShowWhenLocked); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } + ActivityClient.getInstance().setInheritShowWhenLocked(mToken, inheritShowWhenLocked); } /** @@ -8741,11 +8593,7 @@ public class Activity extends ContextThemeWrapper * @see KeyguardManager#isDeviceSecure() */ public void setTurnScreenOn(boolean turnScreenOn) { - try { - ActivityTaskManager.getService().setTurnScreenOn(mToken, turnScreenOn); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } + ActivityClient.getInstance().setTurnScreenOn(mToken, turnScreenOn); } /** @@ -8757,11 +8605,7 @@ public class Activity extends ContextThemeWrapper */ @RequiresPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS) public void registerRemoteAnimations(RemoteAnimationDefinition definition) { - try { - ActivityTaskManager.getService().registerRemoteAnimations(mToken, definition); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } + ActivityClient.getInstance().registerRemoteAnimations(mToken, definition); } /** @@ -8771,11 +8615,7 @@ public class Activity extends ContextThemeWrapper */ @RequiresPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS) public void unregisterRemoteAnimations() { - try { - ActivityTaskManager.getService().unregisterRemoteAnimations(mToken); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } + ActivityClient.getInstance().unregisterRemoteAnimations(mToken); } class HostCallbacks extends FragmentHostCallback<Activity> { diff --git a/core/java/android/app/ActivityClient.java b/core/java/android/app/ActivityClient.java new file mode 100644 index 000000000000..84ecd24b8c55 --- /dev/null +++ b/core/java/android/app/ActivityClient.java @@ -0,0 +1,476 @@ +/* + * Copyright (C) 2020 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 android.app; + +import android.content.ComponentName; +import android.content.Intent; +import android.content.res.Configuration; +import android.os.Bundle; +import android.os.IBinder; +import android.os.PersistableBundle; +import android.os.RemoteException; +import android.util.Singleton; +import android.view.RemoteAnimationDefinition; + +/** + * Provides the activity associated operations that communicate with system. + * + * @hide + */ +public class ActivityClient { + private ActivityClient() {} + + /** Reports the main thread is idle after the activity is resumed. */ + public void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { + try { + getActivityClientController().activityIdle(token, config, stopProfiling); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + + /** Reports {@link Activity#onResume()} is done. */ + public void activityResumed(IBinder token) { + try { + getActivityClientController().activityResumed(token); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + + /** + * Reports after {@link Activity#onTopResumedActivityChanged(boolean)} is called for losing the + * top most position. + */ + public void activityTopResumedStateLost() { + try { + getActivityClientController().activityTopResumedStateLost(); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + + /** Reports {@link Activity#onPause()} is done. */ + public void activityPaused(IBinder token) { + try { + getActivityClientController().activityPaused(token); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + + /** Reports {@link Activity#onStop()} is done. */ + public void activityStopped(IBinder token, Bundle state, PersistableBundle persistentState, + CharSequence description) { + try { + getActivityClientController().activityStopped(token, state, persistentState, + description); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + + /** Reports {@link Activity#onDestroy()} is done. */ + public void activityDestroyed(IBinder token) { + try { + getActivityClientController().activityDestroyed(token); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + + /** Reports the activity has completed relaunched. */ + public void activityRelaunched(IBinder token) { + try { + getActivityClientController().activityRelaunched(token); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + + void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration, + int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) { + try { + getActivityClientController().reportSizeConfigurations(token, + horizontalSizeConfiguration, verticalSizeConfigurations, + smallestSizeConfigurations); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + + public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { + try { + return getActivityClientController().moveActivityTaskToBack(token, nonRoot); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + boolean shouldUpRecreateTask(IBinder token, String destAffinity) { + try { + return getActivityClientController().shouldUpRecreateTask(token, destAffinity); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, + Intent resultData) { + try { + return getActivityClientController().navigateUpTo(token, destIntent, resultCode, + resultData); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + boolean releaseActivityInstance(IBinder token) { + try { + return getActivityClientController().releaseActivityInstance(token); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + public boolean finishActivity(IBinder token, int resultCode, Intent resultData, + int finishTask) { + try { + return getActivityClientController().finishActivity(token, resultCode, resultData, + finishTask); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + boolean finishActivityAffinity(IBinder token) { + try { + return getActivityClientController().finishActivityAffinity(token); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + void finishSubActivity(IBinder token, String resultWho, int requestCode) { + try { + getActivityClientController().finishSubActivity(token, resultWho, requestCode); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + + public boolean isTopOfTask(IBinder token) { + try { + return getActivityClientController().isTopOfTask(token); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + boolean willActivityBeVisible(IBinder token) { + try { + return getActivityClientController().willActivityBeVisible(token); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + public int getDisplayId(IBinder token) { + try { + return getActivityClientController().getDisplayId(token); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + public int getTaskForActivity(IBinder token, boolean onlyRoot) { + try { + return getActivityClientController().getTaskForActivity(token, onlyRoot); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + ComponentName getCallingActivity(IBinder token) { + try { + return getActivityClientController().getCallingActivity(token); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + String getCallingPackage(IBinder token) { + try { + return getActivityClientController().getCallingPackage(token); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + Bundle getActivityOptions(IBinder token) { + try { + return getActivityClientController().getActivityOptions(token); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + public void setRequestedOrientation(IBinder token, int requestedOrientation) { + try { + getActivityClientController().setRequestedOrientation(token, requestedOrientation); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + + int getRequestedOrientation(IBinder token) { + try { + return getActivityClientController().getRequestedOrientation(token); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + boolean convertFromTranslucent(IBinder token) { + try { + return getActivityClientController().convertFromTranslucent(token); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + boolean convertToTranslucent(IBinder token, Bundle options) { + try { + return getActivityClientController().convertToTranslucent(token, options); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) { + try { + getActivityClientController().reportActivityFullyDrawn(token, restoredFromBundle); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + + boolean isImmersive(IBinder token) { + try { + return getActivityClientController().isImmersive(token); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + void setImmersive(IBinder token, boolean immersive) { + try { + getActivityClientController().setImmersive(token, immersive); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + + boolean enterPictureInPictureMode(IBinder token, PictureInPictureParams params) { + try { + return getActivityClientController().enterPictureInPictureMode(token, params); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + void setPictureInPictureParams(IBinder token, PictureInPictureParams params) { + try { + getActivityClientController().setPictureInPictureParams(token, params); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + + void toggleFreeformWindowingMode(IBinder token) { + try { + getActivityClientController().toggleFreeformWindowingMode(token); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + + void startLockTaskModeByToken(IBinder token) { + try { + getActivityClientController().startLockTaskModeByToken(token); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + + void stopLockTaskModeByToken(IBinder token) { + try { + getActivityClientController().stopLockTaskModeByToken(token); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + + void showLockTaskEscapeMessage(IBinder token) { + try { + getActivityClientController().showLockTaskEscapeMessage(token); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + + void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { + try { + getActivityClientController().setTaskDescription(token, td); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + + boolean showAssistFromActivity(IBinder token, Bundle args) { + try { + return getActivityClientController().showAssistFromActivity(token, args); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + boolean isRootVoiceInteraction(IBinder token) { + try { + return getActivityClientController().isRootVoiceInteraction(token); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + void startLocalVoiceInteraction(IBinder callingActivity, Bundle options) { + try { + getActivityClientController().startLocalVoiceInteraction(callingActivity, options); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + + void stopLocalVoiceInteraction(IBinder callingActivity) { + try { + getActivityClientController().stopLocalVoiceInteraction(callingActivity); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + + void setShowWhenLocked(IBinder token, boolean showWhenLocked) { + try { + getActivityClientController().setShowWhenLocked(token, showWhenLocked); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + + void setInheritShowWhenLocked(IBinder token, boolean inheritShowWhenLocked) { + try { + getActivityClientController().setInheritShowWhenLocked(token, inheritShowWhenLocked); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + + void setTurnScreenOn(IBinder token, boolean turnScreenOn) { + try { + getActivityClientController().setTurnScreenOn(token, turnScreenOn); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + + int setVrMode(IBinder token, boolean enabled, ComponentName packageName) { + try { + return getActivityClientController().setVrMode(token, enabled, packageName); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + void overridePendingTransition(IBinder token, String packageName, + int enterAnim, int exitAnim) { + try { + getActivityClientController().overridePendingTransition(token, packageName, + enterAnim, exitAnim); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + + void setDisablePreviewScreenshots(IBinder token, boolean disable) { + try { + getActivityClientController().setDisablePreviewScreenshots(token, disable); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + + void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition) { + try { + getActivityClientController().registerRemoteAnimations(token, definition); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + + void unregisterRemoteAnimations(IBinder token) { + try { + getActivityClientController().unregisterRemoteAnimations(token); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + + void onBackPressedOnTaskRoot(IBinder token) { + try { + getActivityClientController().onBackPressedOnTaskRoot(token); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + + public static ActivityClient getInstance() { + return sInstance.get(); + } + + private static IActivityClientController getActivityClientController() { + return sActivityClientController.get(); + } + + private static final Singleton<ActivityClient> sInstance = new Singleton<ActivityClient>() { + @Override + protected ActivityClient create() { + return new ActivityClient(); + } + }; + + private static final Singleton<IActivityClientController> sActivityClientController = + new Singleton<IActivityClientController>() { + @Override + protected IActivityClientController create() { + try { + return ActivityTaskManager.getService().getActivityClientController(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + }; +} diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 2e08fc80b179..433182b38efd 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -2154,7 +2154,7 @@ public final class ActivityThread extends ClientTransactionHandler { } if (a != null) { mNewActivities = null; - IActivityTaskManager am = ActivityTaskManager.getService(); + final ActivityClient ac = ActivityClient.getInstance(); ActivityClientRecord prev; do { if (localLOGV) Slog.v( @@ -2162,12 +2162,8 @@ public final class ActivityThread extends ClientTransactionHandler { " finished=" + (a.activity != null && a.activity.mFinished)); if (a.activity != null && !a.activity.mFinished) { - try { - am.activityIdle(a.token, a.createdConfig, stopProfiling); - a.createdConfig = null; - } catch (RemoteException ex) { - throw ex.rethrowFromSystemServer(); - } + ac.activityIdle(a.token, a.createdConfig, stopProfiling); + a.createdConfig = null; } prev = a; a = a.nextIdle; @@ -3576,13 +3572,7 @@ public final class ActivityThread extends ClientTransactionHandler { } private ContextImpl createBaseContextForActivity(ActivityClientRecord r) { - final int displayId; - try { - displayId = ActivityTaskManager.getService().getDisplayId(r.token); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - + final int displayId = ActivityClient.getInstance().getDisplayId(r.token); ContextImpl appContext = ContextImpl.createActivityContext( this, r.packageInfo, r.activityInfo, r.token, displayId, r.overrideConfig); @@ -3669,13 +3659,8 @@ public final class ActivityThread extends ClientTransactionHandler { } } else { // If there was an error, for any reason, tell the activity manager to stop us. - try { - ActivityTaskManager.getService() - .finishActivity(r.token, Activity.RESULT_CANCELED, null, - Activity.DONT_FINISH_TASK_WITH_ACTIVITY); - } catch (RemoteException ex) { - throw ex.rethrowFromSystemServer(); - } + ActivityClient.getInstance().finishActivity(r.token, Activity.RESULT_CANCELED, + null /* resultData */, Activity.DONT_FINISH_TASK_WITH_ACTIVITY); } return a; @@ -3705,12 +3690,8 @@ public final class ActivityThread extends ClientTransactionHandler { smallest.put(config.smallestScreenWidthDp, 0); } } - try { - ActivityTaskManager.getService().reportSizeConfigurations(r.token, - horizontal.copyKeys(), vertical.copyKeys(), smallest.copyKeys()); - } catch (RemoteException ex) { - throw ex.rethrowFromSystemServer(); - } + ActivityClient.getInstance().reportSizeConfigurations(r.token, horizontal.copyKeys(), + vertical.copyKeys(), smallest.copyKeys()); } private void deliverNewIntents(ActivityClientRecord r, List<ReferrerIntent> intents) { @@ -4559,12 +4540,8 @@ public final class ActivityThread extends ClientTransactionHandler { // then go ahead and add the window. boolean willBeVisible = !a.mStartedActivity; if (!willBeVisible) { - try { - willBeVisible = ActivityTaskManager.getService().willActivityBeVisible( - a.getActivityToken()); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } + willBeVisible = ActivityClient.getInstance().willActivityBeVisible( + a.getActivityToken()); } if (r.window == null && !a.mFinished && willBeVisible) { r.window = r.activity.getWindow(); @@ -5209,11 +5186,7 @@ public final class ActivityThread extends ClientTransactionHandler { ((ContextImpl) c).scheduleFinalCleanup(r.activity.getClass().getName(), "Activity"); } if (finishing) { - try { - ActivityTaskManager.getService().activityDestroyed(r.token); - } catch (RemoteException ex) { - throw ex.rethrowFromSystemServer(); - } + ActivityClient.getInstance().activityDestroyed(r.token); } mSomeActivitiesChanged = true; } @@ -5477,13 +5450,9 @@ public final class ActivityThread extends ClientTransactionHandler { @Override public void reportRelaunch(ActivityClientRecord r, PendingTransactionActions pendingActions) { - try { - ActivityTaskManager.getService().activityRelaunched(r.token); - if (pendingActions.shouldReportRelaunchToWindowManager() && r.window != null) { - r.window.reportActivityRelaunched(); - } - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + ActivityClient.getInstance().activityRelaunched(r.token); + if (pendingActions.shouldReportRelaunchToWindowManager() && r.window != null) { + r.window.reportActivityRelaunched(); } } diff --git a/core/java/android/app/IActivityClientController.aidl b/core/java/android/app/IActivityClientController.aidl new file mode 100644 index 000000000000..f9449f241545 --- /dev/null +++ b/core/java/android/app/IActivityClientController.aidl @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2020 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 android.app; + +import android.app.ActivityManager; +import android.app.PictureInPictureParams; +import android.content.ComponentName; +import android.content.Intent; +import android.content.res.Configuration; +import android.os.Bundle; +import android.os.PersistableBundle; +import android.view.RemoteAnimationDefinition; + +/** + * Interface for the callback and request from an activity to system. + * + * {@hide} + */ +interface IActivityClientController { + oneway void activityIdle(in IBinder token, in Configuration config, in boolean stopProfiling); + void activityResumed(in IBinder token); + void activityTopResumedStateLost(); + void activityPaused(in IBinder token); + void activityStopped(in IBinder token, in Bundle state, in PersistableBundle persistentState, + in CharSequence description); + oneway void activityDestroyed(in IBinder token); + void activityRelaunched(in IBinder token); + + void reportSizeConfigurations(in IBinder token, in int[] horizontalSizeConfiguration, + in int[] verticalSizeConfigurations, in int[] smallestWidthConfigurations); + boolean moveActivityTaskToBack(in IBinder token, boolean nonRoot); + boolean shouldUpRecreateTask(in IBinder token, in String destAffinity); + boolean navigateUpTo(in IBinder token, in Intent target, int resultCode, + in Intent resultData); + boolean releaseActivityInstance(in IBinder token); + boolean finishActivity(in IBinder token, int code, in Intent data, int finishTask); + boolean finishActivityAffinity(in IBinder token); + /** Finish all activities that were started for result from the specified activity. */ + void finishSubActivity(in IBinder token, in String resultWho, int requestCode); + + boolean isTopOfTask(in IBinder token); + boolean willActivityBeVisible(in IBinder token); + int getDisplayId(in IBinder activityToken); + int getTaskForActivity(in IBinder token, in boolean onlyRoot); + ComponentName getCallingActivity(in IBinder token); + String getCallingPackage(in IBinder token); + Bundle getActivityOptions(in IBinder token); + + void setRequestedOrientation(in IBinder token, int requestedOrientation); + int getRequestedOrientation(in IBinder token); + + boolean convertFromTranslucent(in IBinder token); + boolean convertToTranslucent(in IBinder token, in Bundle options); + + boolean isImmersive(in IBinder token); + void setImmersive(in IBinder token, boolean immersive); + + boolean enterPictureInPictureMode(in IBinder token, in PictureInPictureParams params); + void setPictureInPictureParams(in IBinder token, in PictureInPictureParams params); + void toggleFreeformWindowingMode(in IBinder token); + + void startLockTaskModeByToken(in IBinder token); + void stopLockTaskModeByToken(in IBinder token); + oneway void showLockTaskEscapeMessage(in IBinder token); + void setTaskDescription(in IBinder token, in ActivityManager.TaskDescription values); + + boolean showAssistFromActivity(in IBinder token, in Bundle args); + boolean isRootVoiceInteraction(in IBinder token); + void startLocalVoiceInteraction(in IBinder token, in Bundle options); + void stopLocalVoiceInteraction(in IBinder token); + + void setShowWhenLocked(in IBinder token, boolean showWhenLocked); + void setInheritShowWhenLocked(in IBinder token, boolean setInheritShownWhenLocked); + void setTurnScreenOn(in IBinder token, boolean turnScreenOn); + void reportActivityFullyDrawn(in IBinder token, boolean restoredFromBundle); + void overridePendingTransition(in IBinder token, in String packageName, + int enterAnim, int exitAnim); + int setVrMode(in IBinder token, boolean enabled, in ComponentName packageName); + + /** See {@link android.app.Activity#setDisablePreviewScreenshots}. */ + void setDisablePreviewScreenshots(in IBinder token, boolean disable); + + /** Registers remote animations for a specific activity. */ + void registerRemoteAnimations(in IBinder token, in RemoteAnimationDefinition definition); + + /** Unregisters all remote animations for a specific activity. */ + void unregisterRemoteAnimations(in IBinder token); + + /** + * Reports that an Activity received a back key press when there were no additional activities + * on the back stack. + */ + void onBackPressedOnTaskRoot(in IBinder token); +} diff --git a/core/java/android/app/IActivityTaskManager.aidl b/core/java/android/app/IActivityTaskManager.aidl index ab48baea48e8..4b2557389382 100644 --- a/core/java/android/app/IActivityTaskManager.aidl +++ b/core/java/android/app/IActivityTaskManager.aidl @@ -22,6 +22,7 @@ import android.app.ApplicationErrorReport; import android.app.ContentProviderHolder; import android.app.GrantedUriPermission; import android.app.IApplicationThread; +import android.app.IActivityClientController; import android.app.IActivityController; import android.app.IAppTask; import android.app.IAssistDataReceiver; @@ -35,7 +36,6 @@ import android.app.IUidObserver; import android.app.IUserSwitchObserver; import android.app.Notification; import android.app.PendingIntent; -import android.app.PictureInPictureParams; import android.app.ProfilerInfo; import android.app.WaitResult; import android.app.assist.AssistContent; @@ -63,7 +63,6 @@ import android.os.Debug; import android.os.IBinder; import android.os.IProgressListener; import android.os.ParcelFileDescriptor; -import android.os.PersistableBundle; import android.os.StrictMode; import android.os.WorkSource; import android.service.voice.IVoiceInteractionSession; @@ -144,54 +143,25 @@ interface IActivityTaskManager { int userId); void unhandledBack(); - boolean finishActivity(in IBinder token, int code, in Intent data, int finishTask); - boolean finishActivityAffinity(in IBinder token); - - oneway void activityIdle(in IBinder token, in Configuration config, - in boolean stopProfiling); - void activityResumed(in IBinder token); - void activityTopResumedStateLost(); - void activityPaused(in IBinder token); - void activityStopped(in IBinder token, in Bundle state, - in PersistableBundle persistentState, in CharSequence description); - oneway void activityDestroyed(in IBinder token); - void activityRelaunched(in IBinder token); + + /** Returns an interface to control the activity related operations. */ + IActivityClientController getActivityClientController(); + int getFrontActivityScreenCompatMode(); void setFrontActivityScreenCompatMode(int mode); - String getCallingPackage(in IBinder token); - ComponentName getCallingActivity(in IBinder token); void setFocusedTask(int taskId); boolean removeTask(int taskId); void removeAllVisibleRecentTasks(); List<ActivityManager.RunningTaskInfo> getTasks(int maxNum, boolean filterOnlyVisibleRecents); - boolean shouldUpRecreateTask(in IBinder token, in String destAffinity); - boolean navigateUpTo(in IBinder token, in Intent target, int resultCode, - in Intent resultData); void moveTaskToFront(in IApplicationThread app, in String callingPackage, int task, int flags, in Bundle options); - int getTaskForActivity(in IBinder token, in boolean onlyRoot); - /** Finish all activities that were started for result from the specified activity. */ - void finishSubActivity(in IBinder token, in String resultWho, int requestCode); ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId); - boolean willActivityBeVisible(in IBinder token); - void setRequestedOrientation(in IBinder token, int requestedOrientation); - int getRequestedOrientation(in IBinder token); - boolean convertFromTranslucent(in IBinder token); - boolean convertToTranslucent(in IBinder token, in Bundle options); - void notifyActivityDrawn(in IBinder token); - void reportActivityFullyDrawn(in IBinder token, boolean restoredFromBundle); - int getDisplayId(in IBinder activityToken); - boolean isImmersive(in IBinder token); - void setImmersive(in IBinder token, boolean immersive); boolean isTopActivityImmersive(); - boolean moveActivityTaskToBack(in IBinder token, boolean nonRoot); ActivityManager.TaskDescription getTaskDescription(int taskId); - void overridePendingTransition(in IBinder token, in String packageName, - int enterAnim, int exitAnim); int getLaunchedFromUid(in IBinder activityToken); String getLaunchedFromPackage(in IBinder activityToken); - void reportAssistContextExtras(in IBinder token, in Bundle extras, + void reportAssistContextExtras(in IBinder assistToken, in Bundle extras, in AssistStructure structure, in AssistContent content, in Uri referrer); void setFocusedRootTask(int taskId); @@ -199,24 +169,16 @@ interface IActivityTaskManager { Rect getTaskBounds(int taskId); void cancelRecentsAnimation(boolean restoreHomeRootTaskPosition); - void startLockTaskModeByToken(in IBinder token); - void stopLockTaskModeByToken(in IBinder token); void updateLockTaskPackages(int userId, in String[] packages); boolean isInLockTaskMode(); int getLockTaskModeState(); - void setTaskDescription(in IBinder token, in ActivityManager.TaskDescription values); - Bundle getActivityOptions(in IBinder token); List<IBinder> getAppTasks(in String callingPackage); void startSystemLockTaskMode(int taskId); void stopSystemLockTaskMode(); void finishVoiceTask(in IVoiceInteractionSession session); - boolean isTopOfTask(in IBinder token); - void notifyLaunchTaskBehindComplete(in IBinder token); - void notifyEnterAnimationComplete(in IBinder token); int addAppTask(in IBinder activityToken, in Intent intent, in ActivityManager.TaskDescription description, in Bitmap thumbnail); Point getAppTaskThumbnailSize(); - boolean releaseActivityInstance(in IBinder token); /** * Only callable from the system. This token grants a temporary permission to call * #startActivityAsCallerWithToken. The token will time out after @@ -236,7 +198,6 @@ interface IActivityTaskManager { void registerTaskStackListener(in ITaskStackListener listener); void unregisterTaskStackListener(in ITaskStackListener listener); void setTaskResizeable(int taskId, int resizeableMode); - void toggleFreeformWindowingMode(in IBinder token); /** * Resize the task with given bounds @@ -287,9 +248,6 @@ interface IActivityTaskManager { boolean requestAutofillData(in IAssistDataReceiver receiver, in Bundle receiverExtras, in IBinder activityToken, int flags); boolean isAssistDataAllowedOnCurrentActivity(); - boolean showAssistFromActivity(in IBinder token, in Bundle args); - boolean isRootVoiceInteraction(in IBinder token); - oneway void showLockTaskEscapeMessage(in IBinder token); /** * Notify the system that the keyguard is going away. @@ -302,15 +260,9 @@ interface IActivityTaskManager { ComponentName getActivityClassForToken(in IBinder token); String getPackageForToken(in IBinder token); - void reportSizeConfigurations(in IBinder token, in int[] horizontalSizeConfiguration, - in int[] verticalSizeConfigurations, in int[] smallestWidthConfigurations); - void suppressResizeConfigChanges(boolean suppress); boolean moveTopActivityToPinnedRootTask(int rootTaskId, in Rect bounds); - boolean enterPictureInPictureMode(in IBinder token, in PictureInPictureParams params); - void setPictureInPictureParams(in IBinder token, in PictureInPictureParams params); void requestPictureInPictureMode(in IBinder token); - IBinder getUriPermissionOwnerForActivity(in IBinder activityToken); /** * Resizes the docked stack, and all other stacks as the result of the dock stack bounds change. @@ -343,9 +295,6 @@ interface IActivityTaskManager { * are changing the docked stack size. */ void setSplitScreenResizing(boolean resizing); - int setVrMode(in IBinder token, boolean enabled, in ComponentName packageName); - void startLocalVoiceInteraction(in IBinder token, in Bundle options); - void stopLocalVoiceInteraction(in IBinder token); boolean supportsLocalVoiceInteraction(); // Get device configuration @@ -366,11 +315,6 @@ interface IActivityTaskManager { ActivityManager.TaskSnapshot getTaskSnapshot(int taskId, boolean isLowResolution); /** - * See {@link android.app.Activity#setDisablePreviewScreenshots} - */ - void setDisablePreviewScreenshots(IBinder token, boolean disable); - - /** * 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 @@ -393,20 +337,6 @@ interface IActivityTaskManager { boolean updateConfiguration(in Configuration values); void updateLockTaskFeatures(int userId, int flags); - void setShowWhenLocked(in IBinder token, boolean showWhenLocked); - void setInheritShowWhenLocked(in IBinder token, boolean setInheritShownWhenLocked); - void setTurnScreenOn(in IBinder token, boolean turnScreenOn); - - /** - * Registers remote animations for a specific activity. - */ - void registerRemoteAnimations(in IBinder token, in RemoteAnimationDefinition definition); - - /** - * Unregisters all remote animations for a specific activity. - */ - void unregisterRemoteAnimations(in IBinder token); - /** * Registers a remote animation to be run for all activity starts from a certain package during * a short predefined amount of time. @@ -448,10 +378,4 @@ interface IActivityTaskManager { * @param activityToken The token of the target activity to restart. */ void restartActivityProcessIfVisible(in IBinder activityToken); - - /** - * Reports that an Activity received a back key press when there were no additional activities - * on the back stack. - */ - void onBackPressedOnTaskRoot(in IBinder activityToken); } diff --git a/core/java/android/app/servertransaction/PauseActivityItem.java b/core/java/android/app/servertransaction/PauseActivityItem.java index f7c645e7cb38..813e0f93a1f7 100644 --- a/core/java/android/app/servertransaction/PauseActivityItem.java +++ b/core/java/android/app/servertransaction/PauseActivityItem.java @@ -20,12 +20,11 @@ import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER; import android.annotation.NonNull; import android.annotation.Nullable; -import android.app.ActivityTaskManager; +import android.app.ActivityClient; import android.app.ActivityThread.ActivityClientRecord; import android.app.ClientTransactionHandler; import android.os.IBinder; import android.os.Parcel; -import android.os.RemoteException; import android.os.Trace; /** @@ -61,12 +60,8 @@ public class PauseActivityItem extends ActivityLifecycleItem { if (mDontReport) { return; } - try { - // TODO(lifecycler): Use interface callback instead of AMS. - ActivityTaskManager.getService().activityPaused(token); - } catch (RemoteException ex) { - throw ex.rethrowFromSystemServer(); - } + // TODO(lifecycler): Use interface callback instead of actual implementation. + ActivityClient.getInstance().activityPaused(token); } diff --git a/core/java/android/app/servertransaction/PendingTransactionActions.java b/core/java/android/app/servertransaction/PendingTransactionActions.java index 52ba8fb73f5f..a47fe821cd01 100644 --- a/core/java/android/app/servertransaction/PendingTransactionActions.java +++ b/core/java/android/app/servertransaction/PendingTransactionActions.java @@ -18,13 +18,11 @@ package android.app.servertransaction; import static android.app.ActivityThread.DEBUG_MEMORY_TRIM; -import android.app.ActivityManager; -import android.app.ActivityTaskManager; +import android.app.ActivityClient; import android.app.ActivityThread.ActivityClientRecord; import android.os.Build; import android.os.Bundle; import android.os.PersistableBundle; -import android.os.RemoteException; import android.os.TransactionTooLargeException; import android.util.Log; import android.util.LogWriter; @@ -142,9 +140,9 @@ public class PendingTransactionActions { try { if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Reporting activity stopped: " + mActivity); // TODO(lifecycler): Use interface callback instead of AMS. - ActivityTaskManager.getService().activityStopped( + ActivityClient.getInstance().activityStopped( mActivity.token, mState, mPersistentState, mDescription); - } catch (RemoteException ex) { + } catch (RuntimeException ex) { // Dump statistics about bundle to help developers debug final LogWriter writer = new LogWriter(Log.WARN, TAG); final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " "); @@ -153,12 +151,12 @@ public class PendingTransactionActions { pw.println("PersistableBundle stats:"); Bundle.dumpStats(pw, mPersistentState); - if (ex instanceof TransactionTooLargeException + if (ex.getCause() instanceof TransactionTooLargeException && mActivity.packageInfo.getTargetSdkVersion() < Build.VERSION_CODES.N) { Log.e(TAG, "App sent too much data in instance state, so it was ignored", ex); return; } - throw ex.rethrowFromSystemServer(); + throw ex; } } } diff --git a/core/java/android/app/servertransaction/ResumeActivityItem.java b/core/java/android/app/servertransaction/ResumeActivityItem.java index b4523f581ba8..d451599cc7b0 100644 --- a/core/java/android/app/servertransaction/ResumeActivityItem.java +++ b/core/java/android/app/servertransaction/ResumeActivityItem.java @@ -20,13 +20,12 @@ import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER; import android.annotation.NonNull; import android.annotation.Nullable; +import android.app.ActivityClient; import android.app.ActivityManager; -import android.app.ActivityTaskManager; import android.app.ActivityThread.ActivityClientRecord; import android.app.ClientTransactionHandler; import android.os.IBinder; import android.os.Parcel; -import android.os.RemoteException; import android.os.Trace; /** @@ -60,12 +59,8 @@ public class ResumeActivityItem extends ActivityLifecycleItem { @Override public void postExecute(ClientTransactionHandler client, IBinder token, PendingTransactionActions pendingActions) { - try { - // TODO(lifecycler): Use interface callback instead of AMS. - ActivityTaskManager.getService().activityResumed(token); - } catch (RemoteException ex) { - throw ex.rethrowFromSystemServer(); - } + // TODO(lifecycler): Use interface callback instead of actual implementation. + ActivityClient.getInstance().activityResumed(token); } @Override diff --git a/core/java/android/app/servertransaction/TopResumedActivityChangeItem.java b/core/java/android/app/servertransaction/TopResumedActivityChangeItem.java index 2b0c1b9869e0..5cd3d68f0326 100644 --- a/core/java/android/app/servertransaction/TopResumedActivityChangeItem.java +++ b/core/java/android/app/servertransaction/TopResumedActivityChangeItem.java @@ -19,12 +19,11 @@ import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER; import android.annotation.NonNull; import android.annotation.Nullable; -import android.app.ActivityTaskManager; +import android.app.ActivityClient; import android.app.ActivityThread.ActivityClientRecord; import android.app.ClientTransactionHandler; import android.os.IBinder; import android.os.Parcel; -import android.os.RemoteException; import android.os.Trace; /** @@ -56,11 +55,7 @@ public class TopResumedActivityChangeItem extends ActivityTransactionItem { // 2. Activity wasn't RESUMED yet, which means that it didn't receive the top state yet. // 3. Activity is PAUSED or in other lifecycle state after PAUSED. In this case top resumed // state loss was already called right before pausing. - try { - ActivityTaskManager.getService().activityTopResumedStateLost(); - } catch (RemoteException ex) { - throw ex.rethrowFromSystemServer(); - } + ActivityClient.getInstance().activityTopResumedStateLost(); } diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java index 9c163783124e..13d9eb9d3c7d 100644 --- a/core/java/android/view/Window.java +++ b/core/java/android/view/Window.java @@ -45,7 +45,6 @@ import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; -import android.os.RemoteException; import android.transition.Scene; import android.transition.Transition; import android.transition.TransitionManager; @@ -635,7 +634,7 @@ public abstract class Window { * Moves the activity between {@link WindowConfiguration#WINDOWING_MODE_FREEFORM} windowing * mode and {@link WindowConfiguration#WINDOWING_MODE_FULLSCREEN}. */ - void toggleFreeformWindowingMode() throws RemoteException; + void toggleFreeformWindowingMode(); /** * Puts the activity in picture-in-picture mode if the activity supports. diff --git a/core/java/com/android/internal/widget/DecorCaptionView.java b/core/java/com/android/internal/widget/DecorCaptionView.java index 21021457377a..362fd7b4e937 100644 --- a/core/java/com/android/internal/widget/DecorCaptionView.java +++ b/core/java/com/android/internal/widget/DecorCaptionView.java @@ -18,9 +18,7 @@ package com.android.internal.widget; import android.content.Context; import android.graphics.Rect; -import android.os.RemoteException; import android.util.AttributeSet; -import android.util.Log; import android.view.GestureDetector; import android.view.MotionEvent; import android.view.View; @@ -72,7 +70,6 @@ import java.util.ArrayList; */ public class DecorCaptionView extends ViewGroup implements View.OnTouchListener, GestureDetector.OnGestureListener { - private final static String TAG = "DecorCaptionView"; private PhoneWindow mOwner = null; private boolean mShow = false; @@ -327,11 +324,7 @@ public class DecorCaptionView extends ViewGroup implements View.OnTouchListener, private void toggleFreeformWindowingMode() { Window.WindowControllerCallback callback = mOwner.getWindowControllerCallback(); if (callback != null) { - try { - callback.toggleFreeformWindowingMode(); - } catch (RemoteException ex) { - Log.e(TAG, "Cannot change task workspace."); - } + callback.toggleFreeformWindowingMode(); } } diff --git a/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java b/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java index 46695d2764dd..a74f580b65e6 100644 --- a/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java +++ b/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java @@ -38,13 +38,11 @@ import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.never; import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; import android.app.Activity; -import android.app.ActivityTaskManager; +import android.app.ActivityClient; import android.app.ActivityThread; import android.app.ActivityThread.ActivityClientRecord; -import android.app.IActivityTaskManager; import android.app.LoadedApk; import android.app.servertransaction.PendingTransactionActions; import android.content.ComponentName; @@ -54,7 +52,6 @@ import android.content.pm.ApplicationInfo; import android.content.res.CompatibilityInfo; import android.content.res.Configuration; import android.os.IBinder; -import android.os.RemoteException; import android.os.UserHandle; import android.platform.test.annotations.Presubmit; import android.testing.PollingCheck; @@ -224,18 +221,19 @@ public class ActivityThreadClientTest { private MockitoSession mMockSession; private ActivityThread mThread; - private ClientMockSession() throws RemoteException { + private ClientMockSession() { mThread = ActivityThread.currentActivityThread(); mMockSession = mockitoSession() .strictness(Strictness.LENIENT) - .spyStatic(ActivityTaskManager.class) + .spyStatic(ActivityClient.class) .spyStatic(WindowManagerGlobal.class) .startMocking(); doReturn(Mockito.mock(WindowManagerGlobal.class)) .when(WindowManagerGlobal::getInstance); - IActivityTaskManager mockAtm = Mockito.mock(IActivityTaskManager.class); - doReturn(mockAtm).when(ActivityTaskManager::getService); - when(mockAtm.finishActivity(any(), anyInt(), any(), anyInt())).thenReturn(true); + final ActivityClient mockAc = Mockito.mock(ActivityClient.class); + doReturn(mockAc).when(ActivityClient::getInstance); + doReturn(true).when(mockAc).finishActivity(any() /* token */, + anyInt() /* resultCode */, any() /* resultData */, anyInt() /* finishTask */); } private Activity launchActivity(ActivityClientRecord r) { diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json index 6bcab8a34e2c..1dace8125ae1 100644 --- a/data/etc/services.core.protolog.json +++ b/data/etc/services.core.protolog.json @@ -799,12 +799,6 @@ "group": "WM_DEBUG_RECENTS_ANIMATIONS", "at": "com\/android\/server\/wm\/RecentsAnimation.java" }, - "-1155279885": { - "message": "Frontmost changed immersion: %s", - "level": "DEBUG", - "group": "WM_DEBUG_IMMERSIVE", - "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java" - }, "-1144293044": { "message": "SURFACE SET FREEZE LAYER: %s", "level": "INFO", @@ -1219,6 +1213,12 @@ "group": "WM_DEBUG_ORIENTATION", "at": "com\/android\/server\/wm\/RootWindowContainer.java" }, + "-655104359": { + "message": "Frontmost changed immersion: %s", + "level": "DEBUG", + "group": "WM_DEBUG_IMMERSIVE", + "at": "com\/android\/server\/wm\/ActivityClientController.java" + }, "-653156702": { "message": "createAppAnimations()", "level": "DEBUG", @@ -1573,12 +1573,6 @@ "group": "WM_DEBUG_STATES", "at": "com\/android\/server\/wm\/Task.java" }, - "-272719931": { - "message": "startLockTaskModeLocked: %s", - "level": "WARN", - "group": "WM_DEBUG_LOCKTASK", - "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java" - }, "-262984451": { "message": "Relaunch failed %s", "level": "INFO", @@ -2047,6 +2041,12 @@ "group": "WM_DEBUG_ORIENTATION", "at": "com\/android\/server\/wm\/DisplayRotation.java" }, + "295861935": { + "message": "startLockTaskMode: %s", + "level": "WARN", + "group": "WM_DEBUG_LOCKTASK", + "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java" + }, "302969511": { "message": "Task info changed taskId=%d", "level": "VERBOSE", @@ -2557,6 +2557,12 @@ "group": "WM_DEBUG_TASKS", "at": "com\/android\/server\/wm\/TaskDisplayArea.java" }, + "883475718": { + "message": "Report configuration: %s %s %s", + "level": "VERBOSE", + "group": "WM_DEBUG_CONFIGURATION", + "at": "com\/android\/server\/wm\/ActivityClientController.java" + }, "892244061": { "message": "Waiting for drawn %s: removed=%b visible=%b mHasSurface=%b drawState=%d", "level": "INFO", @@ -3097,12 +3103,6 @@ "group": "WM_ERROR", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, - "1576607724": { - "message": "Report configuration: %s %s %s", - "level": "VERBOSE", - "group": "WM_DEBUG_CONFIGURATION", - "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java" - }, "1577579529": { "message": "win=%s destroySurfaces: appStopped=%b win.mWindowRemovalAllowed=%b win.mRemoveOnExit=%b", "level": "ERROR", diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index da6e7ff84525..63128ced8f93 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -139,6 +139,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.Activity; +import android.app.ActivityClient; import android.app.ActivityManager; import android.app.ActivityManager.RunningTaskInfo; import android.app.ActivityManagerInternal; @@ -288,7 +289,6 @@ import android.util.SparseIntArray; import android.util.TimeUtils; import android.util.proto.ProtoOutputStream; import android.util.proto.ProtoUtils; -import android.view.Display; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; @@ -2859,12 +2859,13 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, int finishTask) { - return mActivityTaskManager.finishActivity(token, resultCode, resultData, finishTask); + return ActivityClient.getInstance().finishActivity(token, resultCode, resultData, + finishTask); } @Override public void setRequestedOrientation(IBinder token, int requestedOrientation) { - mActivityTaskManager.setRequestedOrientation(token, requestedOrientation); + ActivityClient.getInstance().setRequestedOrientation(token, requestedOrientation); } @Override @@ -5711,7 +5712,7 @@ public class ActivityManagerService extends IActivityManager.Stub */ @Override public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { - return mActivityTaskManager.moveActivityTaskToBack(token, nonRoot); + return ActivityClient.getInstance().moveActivityTaskToBack(token, nonRoot); } @Override @@ -5746,7 +5747,7 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public int getTaskForActivity(IBinder token, boolean onlyRoot) { - return mActivityTaskManager.getTaskForActivity(token, onlyRoot); + return ActivityClient.getInstance().getTaskForActivity(token, onlyRoot); } @Override @@ -6719,7 +6720,7 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public boolean isTopOfTask(IBinder token) { - return mActivityTaskManager.isTopOfTask(token); + return ActivityClient.getInstance().isTopOfTask(token); } @Override @@ -16305,14 +16306,9 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public ActivityPresentationInfo getActivityPresentationInfo(IBinder token) { - int displayId = Display.INVALID_DISPLAY; - try { - displayId = mActivityTaskManager.getDisplayId(token); - } catch (RemoteException e) { - } - - return new ActivityPresentationInfo(mActivityTaskManager.getTaskForActivity(token, - /*onlyRoot=*/ false), displayId, + final ActivityClient ac = ActivityClient.getInstance(); + return new ActivityPresentationInfo(ac.getTaskForActivity(token, + /*onlyRoot=*/ false), ac.getDisplayId(token), mActivityTaskManager.getActivityClassForToken(token)); } diff --git a/services/core/java/com/android/server/wm/ActivityClientController.java b/services/core/java/com/android/server/wm/ActivityClientController.java new file mode 100644 index 000000000000..9f1152c8e371 --- /dev/null +++ b/services/core/java/com/android/server/wm/ActivityClientController.java @@ -0,0 +1,1046 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.wm; + +import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS; +import static android.app.ActivityTaskManager.INVALID_TASK_ID; +import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; +import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; +import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; +import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; +import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION; +import static android.view.Display.DEFAULT_DISPLAY; +import static android.view.Display.INVALID_DISPLAY; + +import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION; +import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_IMMERSIVE; +import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ALL; +import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH; +import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_VISIBILITY; +import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM; +import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME; +import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_NONE; +import static com.android.server.wm.ActivityTaskManagerService.TAG_SWITCH; +import static com.android.server.wm.ActivityTaskManagerService.enforceNotIsolatedCaller; +import static com.android.server.wm.Task.ActivityState.DESTROYED; +import static com.android.server.wm.Task.ActivityState.DESTROYING; + +import android.app.Activity; +import android.app.ActivityManager; +import android.app.ActivityOptions; +import android.app.ActivityTaskManager; +import android.app.IActivityClientController; +import android.app.PictureInPictureParams; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.content.res.Configuration; +import android.os.Binder; +import android.os.Bundle; +import android.os.IBinder; +import android.os.PersistableBundle; +import android.os.RemoteException; +import android.os.SystemClock; +import android.os.Trace; +import android.service.voice.VoiceInteractionManagerInternal; +import android.util.Slog; +import android.view.RemoteAnimationDefinition; + +import com.android.internal.app.AssistUtils; +import com.android.internal.protolog.common.ProtoLog; +import com.android.server.LocalServices; +import com.android.server.Watchdog; +import com.android.server.uri.NeededUriGrants; +import com.android.server.vr.VrManagerInternal; + +import java.util.Arrays; + +/** + * Server side implementation for the client activity to interact with system. + * + * @see android.app.ActivityClient + */ +class ActivityClientController extends IActivityClientController.Stub { + private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityClientController" : TAG_ATM; + private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY; + + private final ActivityTaskManagerService mService; + private final WindowManagerGlobalLock mGlobalLock; + private final ActivityTaskSupervisor mTaskSupervisor; + private final Context mContext; + + /** Wrapper around VoiceInteractionServiceManager. */ + private AssistUtils mAssistUtils; + + ActivityClientController(ActivityTaskManagerService service) { + mService = service; + mGlobalLock = service.mGlobalLock; + mTaskSupervisor = service.mTaskSupervisor; + mContext = service.mContext; + } + + void onSystemReady() { + mAssistUtils = new AssistUtils(mContext); + } + + @Override + public void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { + final long origId = Binder.clearCallingIdentity(); + try { + synchronized (mGlobalLock) { + Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "activityIdle"); + final ActivityRecord r = ActivityRecord.forTokenLocked(token); + if (r == null) { + return; + } + mTaskSupervisor.activityIdleInternal(r, false /* fromTimeout */, + false /* processPausingActivities */, config); + if (stopProfiling && r.hasProcess()) { + r.app.clearProfilerIfNeeded(); + } + } + } finally { + Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); + Binder.restoreCallingIdentity(origId); + } + } + + @Override + public void activityResumed(IBinder token) { + final long origId = Binder.clearCallingIdentity(); + synchronized (mGlobalLock) { + ActivityRecord.activityResumedLocked(token); + } + Binder.restoreCallingIdentity(origId); + } + + @Override + public void activityTopResumedStateLost() { + final long origId = Binder.clearCallingIdentity(); + synchronized (mGlobalLock) { + mTaskSupervisor.handleTopResumedStateReleased(false /* timeout */); + } + Binder.restoreCallingIdentity(origId); + } + + @Override + public void activityPaused(IBinder token) { + final long origId = Binder.clearCallingIdentity(); + synchronized (mGlobalLock) { + Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "activityPaused"); + final ActivityRecord r = ActivityRecord.forTokenLocked(token); + if (r != null) { + r.activityPaused(false); + } + Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); + } + Binder.restoreCallingIdentity(origId); + } + + @Override + public void activityStopped(IBinder token, Bundle icicle, PersistableBundle persistentState, + CharSequence description) { + if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token); + + // Refuse possible leaked file descriptors. + if (icicle != null && icicle.hasFileDescriptors()) { + throw new IllegalArgumentException("File descriptors passed in Bundle"); + } + + final long origId = Binder.clearCallingIdentity(); + + String restartingName = null; + int restartingUid = 0; + final ActivityRecord r; + synchronized (mGlobalLock) { + Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "activityStopped"); + r = ActivityRecord.isInStackLocked(token); + if (r != null) { + if (r.attachedToProcess() && r.isState(Task.ActivityState.RESTARTING_PROCESS)) { + // The activity was requested to restart from + // {@link #restartActivityProcessIfVisible}. + restartingName = r.app.mName; + restartingUid = r.app.mUid; + } + r.activityStopped(icicle, persistentState, description); + } + Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); + } + + if (restartingName != null) { + // In order to let the foreground activity can be restarted with its saved state from + // {@link android.app.Activity#onSaveInstanceState}, the kill operation is postponed + // until the activity reports stopped with the state. And the activity record will be + // kept because the record state is restarting, then the activity will be restarted + // immediately if it is still the top one. + mTaskSupervisor.removeRestartTimeouts(r); + mService.mAmInternal.killProcess(restartingName, restartingUid, + "restartActivityProcess"); + } + mService.mAmInternal.trimApplications(); + + Binder.restoreCallingIdentity(origId); + } + + @Override + public void activityDestroyed(IBinder token) { + if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token); + final long origId = Binder.clearCallingIdentity(); + synchronized (mGlobalLock) { + Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "activityDestroyed"); + try { + final ActivityRecord r = ActivityRecord.forTokenLocked(token); + if (r != null) { + r.destroyed("activityDestroyed"); + } + } finally { + Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); + Binder.restoreCallingIdentity(origId); + } + } + } + + @Override + public void activityRelaunched(IBinder token) { + final long origId = Binder.clearCallingIdentity(); + synchronized (mGlobalLock) { + mTaskSupervisor.activityRelaunchedLocked(token); + } + Binder.restoreCallingIdentity(origId); + } + + @Override + public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration, + int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) { + ProtoLog.v(WM_DEBUG_CONFIGURATION, "Report configuration: %s %s %s", + token, Arrays.toString(horizontalSizeConfiguration), + Arrays.toString(verticalSizeConfigurations)); + synchronized (mGlobalLock) { + final ActivityRecord r = ActivityRecord.isInStackLocked(token); + if (r != null) { + r.setSizeConfigurations(horizontalSizeConfiguration, verticalSizeConfigurations, + smallestSizeConfigurations); + } + } + } + + /** + * Attempts to move a task backwards in z-order (the order of activities within the task is + * unchanged). + * + * There are several possible results of this call: + * - if the task is locked, then we will show the lock toast. + * - if there is a task behind the provided task, then that task is made visible and resumed as + * this task is moved to the back. + * - otherwise, if there are no other tasks in the root task: + * - if this task is in the pinned mode, then we remove the task completely, which will + * have the effect of moving the task to the top or bottom of the fullscreen root task + * (depending on whether it is visible). + * - otherwise, we simply return home and hide this task. + * + * @param token A reference to the activity we wish to move. + * @param nonRoot If false then this only works if the activity is the root + * of a task; if true it will work for any activity in a task. + * @return Returns true if the move completed, false if not. + */ + @Override + public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { + enforceNotIsolatedCaller("moveActivityTaskToBack"); + final long origId = Binder.clearCallingIdentity(); + try { + synchronized (mGlobalLock) { + final int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); + final Task task = mService.mRootWindowContainer.anyTaskForId(taskId); + if (task != null) { + return ActivityRecord.getStackLocked(token).moveTaskToBack(task); + } + } + } finally { + Binder.restoreCallingIdentity(origId); + } + return false; + } + + @Override + public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { + synchronized (mGlobalLock) { + final ActivityRecord srec = ActivityRecord.forTokenLocked(token); + if (srec != null) { + return srec.getRootTask().shouldUpRecreateTaskLocked(srec, destAffinity); + } + } + return false; + } + + @Override + public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, + Intent resultData) { + final ActivityRecord r; + synchronized (mGlobalLock) { + r = ActivityRecord.isInStackLocked(token); + if (r == null) { + return false; + } + } + + // Carefully collect grants without holding lock. + final NeededUriGrants destGrants = mService.collectGrants(destIntent, r); + final NeededUriGrants resultGrants = mService.collectGrants(resultData, r.resultTo); + + synchronized (mGlobalLock) { + return r.getRootTask().navigateUpTo( + r, destIntent, destGrants, resultCode, resultData, resultGrants); + } + } + + @Override + public boolean releaseActivityInstance(IBinder token) { + final long origId = Binder.clearCallingIdentity(); + try { + synchronized (mGlobalLock) { + final ActivityRecord r = ActivityRecord.isInStackLocked(token); + if (r == null || !r.isDestroyable()) { + return false; + } + r.destroyImmediately("app-req"); + return r.isState(DESTROYING, DESTROYED); + } + } finally { + Binder.restoreCallingIdentity(origId); + } + } + + /** + * This is the internal entry point for handling Activity.finish(). + * + * @param token The Binder token referencing the Activity we want to finish. + * @param resultCode Result code, if any, from this Activity. + * @param resultData Result data (Intent), if any, from this Activity. + * @param finishTask Whether to finish the task associated with this Activity. + * @return Returns true if the activity successfully finished, or false if it is still running. + */ + @Override + public boolean finishActivity(IBinder token, int resultCode, Intent resultData, + int finishTask) { + // Refuse possible leaked file descriptors. + if (resultData != null && resultData.hasFileDescriptors()) { + throw new IllegalArgumentException("File descriptors passed in Intent"); + } + + final ActivityRecord r; + synchronized (mGlobalLock) { + r = ActivityRecord.isInStackLocked(token); + if (r == null) { + return true; + } + } + + // Carefully collect grants without holding lock. + final NeededUriGrants resultGrants = mService.collectGrants(resultData, r.resultTo); + + synchronized (mGlobalLock) { + // Check again in case activity was removed when collecting grants. + if (!r.isInHistory()) { + return true; + } + + // Keep track of the root activity of the task before we finish it. + final Task tr = r.getTask(); + final ActivityRecord rootR = tr.getRootActivity(); + if (rootR == null) { + Slog.w(TAG, "Finishing task with all activities already finished"); + } + // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can + // finish. + if (mService.getLockTaskController().activityBlockedFromFinish(r)) { + return false; + } + + // TODO: There is a dup. of this block of code in ActivityStack.navigateUpToLocked + // We should consolidate. + if (mService.mController != null) { + // Find the first activity that is not finishing. + final ActivityRecord next = + r.getRootTask().topRunningActivity(token, INVALID_TASK_ID); + if (next != null) { + // ask watcher if this is allowed + boolean resumeOK = true; + try { + resumeOK = mService.mController.activityResuming(next.packageName); + } catch (RemoteException e) { + mService.mController = null; + Watchdog.getInstance().setActivityController(null); + } + + if (!resumeOK) { + Slog.i(TAG, "Not finishing activity because controller resumed"); + return false; + } + } + } + + // Note down that the process has finished an activity and is in background activity + // starts grace period. + if (r.app != null) { + r.app.setLastActivityFinishTimeIfNeeded(SystemClock.uptimeMillis()); + } + + final long origId = Binder.clearCallingIdentity(); + Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "finishActivity"); + try { + final boolean res; + final boolean finishWithRootActivity = + finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY; + if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY + || (finishWithRootActivity && r == rootR)) { + // If requested, remove the task that is associated to this activity only if it + // was the root activity in the task. The result code and data is ignored + // because we don't support returning them across task boundaries. Also, to + // keep backwards compatibility we remove the task from recents when finishing + // task with root activity. + mTaskSupervisor.removeTask(tr, false /*killProcess*/, + finishWithRootActivity, "finish-activity"); + res = true; + // Explicitly dismissing the activity so reset its relaunch flag. + r.mRelaunchReason = RELAUNCH_REASON_NONE; + } else { + r.finishIfPossible(resultCode, resultData, resultGrants, + "app-request", true /* oomAdj */); + res = r.finishing; + if (!res) { + Slog.i(TAG, "Failed to finish by app-request"); + } + } + return res; + } finally { + Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); + Binder.restoreCallingIdentity(origId); + } + } + } + + @Override + public boolean finishActivityAffinity(IBinder token) { + final long origId = Binder.clearCallingIdentity(); + try { + synchronized (mGlobalLock) { + final ActivityRecord r = ActivityRecord.isInStackLocked(token); + if (r == null) { + return false; + } + + // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps + // can finish. + if (mService.getLockTaskController().activityBlockedFromFinish(r)) { + return false; + } + + r.getTask().forAllActivities(activity -> r.finishIfSameAffinity(activity), + r /* boundary */, true /* includeBoundary */, + true /* traverseTopToBottom */); + return true; + } + } finally { + Binder.restoreCallingIdentity(origId); + } + } + + @Override + public void finishSubActivity(IBinder token, String resultWho, int requestCode) { + final long origId = Binder.clearCallingIdentity(); + try { + synchronized (mGlobalLock) { + final ActivityRecord r = ActivityRecord.isInStackLocked(token); + if (r == null) return; + + // TODO: This should probably only loop over the task since you need to be in the + // same task to return results. + r.getRootTask().forAllActivities(activity -> { + activity.finishIfSubActivity(r /* parent */, resultWho, requestCode); + }, true /* traverseTopToBottom */); + + mService.updateOomAdj(); + } + } finally { + Binder.restoreCallingIdentity(origId); + } + } + + @Override + public boolean isTopOfTask(IBinder token) { + synchronized (mGlobalLock) { + final ActivityRecord r = ActivityRecord.isInStackLocked(token); + return r != null && r.getTask().getTopNonFinishingActivity() == r; + } + } + + @Override + public boolean willActivityBeVisible(IBinder token) { + synchronized (mGlobalLock) { + final Task rootTask = ActivityRecord.getStackLocked(token); + return rootTask != null && rootTask.willActivityBeVisible(token); + } + } + + @Override + public int getDisplayId(IBinder activityToken) { + synchronized (mGlobalLock) { + final Task rootTask = ActivityRecord.getStackLocked(activityToken); + if (rootTask != null) { + final int displayId = rootTask.getDisplayId(); + return displayId != INVALID_DISPLAY ? displayId : DEFAULT_DISPLAY; + } + return DEFAULT_DISPLAY; + } + } + + @Override + public int getTaskForActivity(IBinder token, boolean onlyRoot) { + synchronized (mGlobalLock) { + return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); + } + } + + @Override + public ComponentName getCallingActivity(IBinder token) { + synchronized (mGlobalLock) { + final ActivityRecord r = getCallingRecord(token); + return r != null ? r.intent.getComponent() : null; + } + } + + @Override + public String getCallingPackage(IBinder token) { + synchronized (mGlobalLock) { + final ActivityRecord r = getCallingRecord(token); + return r != null ? r.info.packageName : null; + } + } + + private static ActivityRecord getCallingRecord(IBinder token) { + final ActivityRecord r = ActivityRecord.isInStackLocked(token); + return r != null ? r.resultTo : null; + } + + @Override + public Bundle getActivityOptions(IBinder token) { + final long origId = Binder.clearCallingIdentity(); + try { + synchronized (mGlobalLock) { + final ActivityRecord r = ActivityRecord.isInStackLocked(token); + if (r == null) { + return null; + } + final ActivityOptions activityOptions = r.takeOptionsLocked(true /* fromClient */); + return activityOptions != null ? activityOptions.toBundle() : null; + } + } finally { + Binder.restoreCallingIdentity(origId); + } + } + + @Override + public void setRequestedOrientation(IBinder token, int requestedOrientation) { + final long origId = Binder.clearCallingIdentity(); + try { + synchronized (mGlobalLock) { + final ActivityRecord r = ActivityRecord.isInStackLocked(token); + if (r != null) { + r.setRequestedOrientation(requestedOrientation); + } + } + } finally { + Binder.restoreCallingIdentity(origId); + } + } + + @Override + public int getRequestedOrientation(IBinder token) { + synchronized (mGlobalLock) { + final ActivityRecord r = ActivityRecord.isInStackLocked(token); + return r != null + ? r.getRequestedOrientation() : ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; + } + } + + @Override + public boolean convertFromTranslucent(IBinder token) { + final long origId = Binder.clearCallingIdentity(); + try { + synchronized (mGlobalLock) { + final ActivityRecord r = ActivityRecord.isInStackLocked(token); + return r != null && r.setOccludesParent(true); + } + } finally { + Binder.restoreCallingIdentity(origId); + } + } + + @Override + public boolean convertToTranslucent(IBinder token, Bundle options) { + final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(options); + final long origId = Binder.clearCallingIdentity(); + try { + synchronized (mGlobalLock) { + final ActivityRecord r = ActivityRecord.isInStackLocked(token); + if (r == null) { + return false; + } + final ActivityRecord under = r.getTask().getActivityBelow(r); + if (under != null) { + under.returningOptions = safeOptions != null ? safeOptions.getOptions(r) : null; + } + return r.setOccludesParent(false); + } + } finally { + Binder.restoreCallingIdentity(origId); + } + } + + @Override + public boolean isImmersive(IBinder token) { + synchronized (mGlobalLock) { + final ActivityRecord r = ActivityRecord.isInStackLocked(token); + if (r == null) { + throw new IllegalArgumentException(); + } + return r.immersive; + } + } + + @Override + public void setImmersive(IBinder token, boolean immersive) { + synchronized (mGlobalLock) { + final ActivityRecord r = ActivityRecord.isInStackLocked(token); + if (r == null) { + throw new IllegalArgumentException(); + } + r.immersive = immersive; + + // Update associated state if we're frontmost. + if (r.isFocusedActivityOnDisplay()) { + ProtoLog.d(WM_DEBUG_IMMERSIVE, "Frontmost changed immersion: %s", r); + mService.applyUpdateLockStateLocked(r); + } + } + } + + @Override + public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) { + final long origId = Binder.clearCallingIdentity(); + try { + synchronized (mGlobalLock) { + final ActivityRecord r = ensureValidPictureInPictureActivityParams( + "enterPictureInPictureMode", token, params); + return mService.enterPictureInPictureMode(r, params); + } + } finally { + Binder.restoreCallingIdentity(origId); + } + } + + @Override + public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) { + final long origId = Binder.clearCallingIdentity(); + try { + synchronized (mGlobalLock) { + final ActivityRecord r = ensureValidPictureInPictureActivityParams( + "setPictureInPictureParams", token, params); + + // Only update the saved args from the args that are set. + r.setPictureInPictureParams(params); + if (r.inPinnedWindowingMode()) { + // If the activity is already in picture-in-picture, update the pinned task now + // if it is not already expanding to fullscreen. Otherwise, the arguments will + // be used the next time the activity enters PiP. + final Task rootTask = r.getRootTask(); + rootTask.setPictureInPictureAspectRatio( + r.pictureInPictureArgs.getAspectRatio()); + rootTask.setPictureInPictureActions(r.pictureInPictureArgs.getActions()); + } + } + } finally { + Binder.restoreCallingIdentity(origId); + } + } + + /** + * Checks the state of the system and the activity associated with the given {@param token} to + * verify that picture-in-picture is supported for that activity. + * + * @return the activity record for the given {@param token} if all the checks pass. + */ + private ActivityRecord ensureValidPictureInPictureActivityParams(String caller, + IBinder token, PictureInPictureParams params) { + if (!mService.mSupportsPictureInPicture) { + throw new IllegalStateException(caller + + ": Device doesn't support picture-in-picture mode."); + } + + final ActivityRecord r = ActivityRecord.forTokenLocked(token); + if (r == null) { + throw new IllegalStateException(caller + + ": Can't find activity for token=" + token); + } + + if (!r.supportsPictureInPicture()) { + throw new IllegalStateException(caller + + ": Current activity does not support picture-in-picture."); + } + + if (params.hasSetAspectRatio() + && !mService.mWindowManager.isValidPictureInPictureAspectRatio( + r.mDisplayContent, params.getAspectRatio())) { + final float minAspectRatio = mContext.getResources().getFloat( + com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio); + final float maxAspectRatio = mContext.getResources().getFloat( + com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio); + throw new IllegalArgumentException(String.format(caller + + ": Aspect ratio is too extreme (must be between %f and %f).", + minAspectRatio, maxAspectRatio)); + } + + // Truncate the number of actions if necessary. + params.truncateActions(ActivityTaskManager.getMaxNumPictureInPictureActions(mContext)); + return r; + } + + @Override + public void toggleFreeformWindowingMode(IBinder token) { + final long ident = Binder.clearCallingIdentity(); + try { + synchronized (mGlobalLock) { + final ActivityRecord r = ActivityRecord.forTokenLocked(token); + if (r == null) { + throw new IllegalArgumentException( + "toggleFreeformWindowingMode: No activity record matching token=" + + token); + } + + final Task rootTask = r.getRootTask(); + if (rootTask == null) { + throw new IllegalStateException("toggleFreeformWindowingMode: the activity " + + "doesn't have a root task"); + } + + if (!rootTask.inFreeformWindowingMode() + && rootTask.getWindowingMode() != WINDOWING_MODE_FULLSCREEN) { + throw new IllegalStateException("toggleFreeformWindowingMode: You can only " + + "toggle between fullscreen and freeform."); + } + + if (rootTask.inFreeformWindowingMode()) { + rootTask.setWindowingMode(WINDOWING_MODE_FULLSCREEN); + } else if (!mService.mSizeCompatFreeform && r.inSizeCompatMode()) { + throw new IllegalStateException("Size-compat windows are currently not" + + "freeform-enabled"); + } else if (rootTask.getParent().inFreeformWindowingMode()) { + // If the window is on a freeform display, set it to undefined. It will be + // resolved to freeform and it can adjust windowing mode when the display mode + // changes in runtime. + rootTask.setWindowingMode(WINDOWING_MODE_UNDEFINED); + } else { + rootTask.setWindowingMode(WINDOWING_MODE_FREEFORM); + } + } + } finally { + Binder.restoreCallingIdentity(ident); + } + } + + @Override + public void startLockTaskModeByToken(IBinder token) { + synchronized (mGlobalLock) { + final ActivityRecord r = ActivityRecord.forTokenLocked(token); + if (r != null) { + mService.startLockTaskMode(r.getTask(), false /* isSystemCaller */); + } + } + } + + @Override + public void stopLockTaskModeByToken(IBinder token) { + mService.stopLockTaskModeInternal(token, false /* isSystemCaller */); + } + + @Override + public void showLockTaskEscapeMessage(IBinder token) { + synchronized (mGlobalLock) { + if (ActivityRecord.forTokenLocked(token) != null) { + mService.getLockTaskController().showLockTaskToast(); + } + } + } + + @Override + public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { + synchronized (mGlobalLock) { + final ActivityRecord r = ActivityRecord.isInStackLocked(token); + if (r != null) { + r.setTaskDescription(td); + } + } + } + + @Override + public boolean showAssistFromActivity(IBinder token, Bundle args) { + final long ident = Binder.clearCallingIdentity(); + try { + synchronized (mGlobalLock) { + final ActivityRecord caller = ActivityRecord.forTokenLocked(token); + final Task topRootTask = mService.getTopDisplayFocusedRootTask(); + final ActivityRecord top = topRootTask != null + ? topRootTask.getTopNonFinishingActivity() : null; + if (top != caller) { + Slog.w(TAG, "showAssistFromActivity failed: caller " + caller + + " is not current top " + top); + return false; + } + if (!top.nowVisible) { + Slog.w(TAG, "showAssistFromActivity failed: caller " + caller + + " is not visible"); + return false; + } + } + return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, + null /* showCallback */, token); + } finally { + Binder.restoreCallingIdentity(ident); + } + } + + @Override + public boolean isRootVoiceInteraction(IBinder token) { + synchronized (mGlobalLock) { + final ActivityRecord r = ActivityRecord.isInStackLocked(token); + return r != null && r.rootVoiceInteraction; + } + } + + @Override + public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options) { + Slog.i(TAG, "Activity tried to startLocalVoiceInteraction"); + synchronized (mGlobalLock) { + final Task topRootTask = mService.getTopDisplayFocusedRootTask(); + final ActivityRecord activity = topRootTask != null + ? topRootTask.getTopNonFinishingActivity() : null; + if (ActivityRecord.forTokenLocked(callingActivity) != activity) { + throw new SecurityException("Only focused activity can call startVoiceInteraction"); + } + if (mService.mRunningVoice != null || activity.getTask().voiceSession != null + || activity.voiceSession != null) { + Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction"); + return; + } + if (activity.pendingVoiceInteractionStart) { + Slog.w(TAG, "Pending start of voice interaction already."); + return; + } + activity.pendingVoiceInteractionStart = true; + } + LocalServices.getService(VoiceInteractionManagerInternal.class) + .startLocalVoiceInteraction(callingActivity, options); + } + + @Override + public void stopLocalVoiceInteraction(IBinder callingActivity) { + LocalServices.getService(VoiceInteractionManagerInternal.class) + .stopLocalVoiceInteraction(callingActivity); + } + + @Override + public void setShowWhenLocked(IBinder token, boolean showWhenLocked) { + final long origId = Binder.clearCallingIdentity(); + try { + synchronized (mGlobalLock) { + final ActivityRecord r = ActivityRecord.isInStackLocked(token); + if (r != null) { + r.setShowWhenLocked(showWhenLocked); + } + } + } finally { + Binder.restoreCallingIdentity(origId); + } + } + + @Override + public void setInheritShowWhenLocked(IBinder token, boolean inheritShowWhenLocked) { + final long origId = Binder.clearCallingIdentity(); + try { + synchronized (mGlobalLock) { + final ActivityRecord r = ActivityRecord.isInStackLocked(token); + if (r != null) { + r.setInheritShowWhenLocked(inheritShowWhenLocked); + } + } + } finally { + Binder.restoreCallingIdentity(origId); + } + } + + @Override + public void setTurnScreenOn(IBinder token, boolean turnScreenOn) { + final long origId = Binder.clearCallingIdentity(); + try { + synchronized (mGlobalLock) { + final ActivityRecord r = ActivityRecord.isInStackLocked(token); + if (r != null) { + r.setTurnScreenOn(turnScreenOn); + } + } + } finally { + Binder.restoreCallingIdentity(origId); + } + } + + @Override + public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) { + final long origId = Binder.clearCallingIdentity(); + try { + synchronized (mGlobalLock) { + final ActivityRecord r = ActivityRecord.isInStackLocked(token); + if (r != null) { + r.reportFullyDrawnLocked(restoredFromBundle); + } + } + } finally { + Binder.restoreCallingIdentity(origId); + } + } + + @Override + public void overridePendingTransition(IBinder token, String packageName, + int enterAnim, int exitAnim) { + final long origId = Binder.clearCallingIdentity(); + synchronized (mGlobalLock) { + final ActivityRecord r = ActivityRecord.isInStackLocked(token); + if (r != null && r.isState(Task.ActivityState.RESUMED, Task.ActivityState.PAUSING)) { + r.mDisplayContent.mAppTransition.overridePendingAppTransition( + packageName, enterAnim, exitAnim, null, null); + } + } + Binder.restoreCallingIdentity(origId); + } + + @Override + public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) { + mService.enforceSystemHasVrFeature(); + + final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class); + final ActivityRecord r; + synchronized (mGlobalLock) { + r = ActivityRecord.isInStackLocked(token); + } + if (r == null) { + throw new IllegalArgumentException(); + } + + final int err; + if ((err = vrService.hasVrPackage(packageName, r.mUserId)) != VrManagerInternal.NO_ERROR) { + return err; + } + + // Clear the binder calling uid since this path may call moveToTask(). + final long callingId = Binder.clearCallingIdentity(); + try { + synchronized (mGlobalLock) { + r.requestedVrComponent = (enabled) ? packageName : null; + + // Update associated state if this activity is currently focused. + if (r.isFocusedActivityOnDisplay()) { + mService.applyUpdateVrModeLocked(r); + } + return 0; + } + } finally { + Binder.restoreCallingIdentity(callingId); + } + } + + @Override + public void setDisablePreviewScreenshots(IBinder token, boolean disable) { + final long origId = Binder.clearCallingIdentity(); + try { + synchronized (mGlobalLock) { + final ActivityRecord r = ActivityRecord.isInStackLocked(token); + if (r != null) { + r.setDisablePreviewScreenshots(disable); + } + } + } finally { + Binder.restoreCallingIdentity(origId); + } + } + + @Override + public void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition) { + mService.mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS, + "registerRemoteAnimations"); + definition.setCallingPidUid(Binder.getCallingPid(), Binder.getCallingUid()); + final long origId = Binder.clearCallingIdentity(); + try { + synchronized (mGlobalLock) { + final ActivityRecord r = ActivityRecord.isInStackLocked(token); + if (r != null) { + r.registerRemoteAnimations(definition); + } + } + } finally { + Binder.restoreCallingIdentity(origId); + } + } + + @Override + public void unregisterRemoteAnimations(IBinder token) { + mService.mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS, + "unregisterRemoteAnimations"); + final long origId = Binder.clearCallingIdentity(); + try { + synchronized (mGlobalLock) { + final ActivityRecord r = ActivityRecord.isInStackLocked(token); + if (r != null) { + r.unregisterRemoteAnimations(); + } + } + } finally { + Binder.restoreCallingIdentity(origId); + } + } + + @Override + public void onBackPressedOnTaskRoot(IBinder token) { + final long origId = Binder.clearCallingIdentity(); + try { + synchronized (mGlobalLock) { + final ActivityRecord r = ActivityRecord.isInStackLocked(token); + if (r == null) { + return; + } + if (mService.mWindowOrganizerController.mTaskOrganizerController + .handleInterceptBackPressedOnTaskRoot(r.getRootTask())) { + // This task is handled by a task organizer that has requested the back pressed + // callback. + } else { + moveActivityTaskToBack(token, false /* nonRoot */); + } + } + } finally { + Binder.restoreCallingIdentity(origId); + } + } +} diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 1b8cc082f598..2e55e92a4dcd 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -4032,7 +4032,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A if (mDisplayContent != null) { mDisplayContent.setLayoutNeeded(); } - mWmService.mH.obtainMessage(H.NOTIFY_ACTIVITY_DRAWN, token).sendToTarget(); + mWmService.mH.obtainMessage(H.NOTIFY_ACTIVITY_DRAWN, this).sendToTarget(); } } } diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index 3710120a7934..8298dfd85114 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -33,8 +33,6 @@ import static android.app.ActivityManagerInternal.ALLOW_NON_FULL; import static android.app.ActivityTaskManager.INVALID_TASK_ID; import static android.app.ActivityTaskManager.RESIZE_MODE_PRESERVE_WINDOW; import static android.app.WindowConfiguration.ACTIVITY_TYPE_DREAM; -import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; -import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; @@ -62,7 +60,6 @@ import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIV import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL; import static android.provider.Settings.Global.HIDE_ERROR_DIALOGS; import static android.provider.Settings.System.FONT_SCALE; -import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION; import static android.text.format.DateUtils.MINUTE_IN_MILLIS; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.INVALID_DISPLAY; @@ -95,15 +92,8 @@ import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.Scr import static com.android.server.am.EventLogTags.writeBootProgressEnableScreen; import static com.android.server.am.EventLogTags.writeConfigurationChanged; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ALL; -import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH; -import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_VISIBILITY; -import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION; -import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_FOCUS; -import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_IMMERSIVE; -import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_LOCKTASK; import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_ROOT_TASK; import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_SWITCH; -import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_VISIBILITY; import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM; import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_CONTENT; @@ -121,8 +111,6 @@ import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_P import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION; import static com.android.server.wm.RootWindowContainer.MATCH_ATTACHED_TASK_ONLY; import static com.android.server.wm.RootWindowContainer.MATCH_ATTACHED_TASK_OR_RECENT_TASKS; -import static com.android.server.wm.Task.ActivityState.DESTROYED; -import static com.android.server.wm.Task.ActivityState.DESTROYING; import static com.android.server.wm.Task.REPARENT_KEEP_ROOT_TASK_AT_FRONT; import static com.android.server.wm.WindowContainer.POSITION_TOP; import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL; @@ -132,7 +120,6 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; -import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityManagerInternal; import android.app.ActivityOptions; @@ -143,6 +130,7 @@ import android.app.AlertDialog; import android.app.AppGlobals; import android.app.AppOpsManager; import android.app.Dialog; +import android.app.IActivityClientController; import android.app.IActivityController; import android.app.IActivityTaskManager; import android.app.IApplicationThread; @@ -197,7 +185,6 @@ import android.os.IUserManager; import android.os.LocaleList; import android.os.Looper; import android.os.Message; -import android.os.PersistableBundle; import android.os.PowerManager; import android.os.PowerManagerInternal; import android.os.Process; @@ -237,7 +224,6 @@ import android.window.WindowContainerTransaction; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.app.AssistUtils; import com.android.internal.app.IVoiceInteractor; import com.android.internal.app.ProcessMap; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; @@ -249,8 +235,6 @@ import com.android.internal.protolog.common.ProtoLog; import com.android.internal.util.ArrayUtils; import com.android.internal.util.FastPrintWriter; import com.android.internal.util.FrameworkStatsLog; -import com.android.internal.util.function.pooled.PooledConsumer; -import com.android.internal.util.function.pooled.PooledFunction; import com.android.internal.util.function.pooled.PooledLambda; import com.android.server.AttributeCache; import com.android.server.LocalServices; @@ -271,7 +255,6 @@ import com.android.server.pm.UserManagerService; import com.android.server.policy.PermissionPolicyInternal; import com.android.server.uri.NeededUriGrants; import com.android.server.uri.UriGrantsManagerInternal; -import com.android.server.vr.VrManagerInternal; import java.io.BufferedReader; import java.io.File; @@ -308,11 +291,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityTaskManagerService" : TAG_ATM; static final String TAG_ROOT_TASK = TAG + POSTFIX_ROOT_TASK; static final String TAG_SWITCH = TAG + POSTFIX_SWITCH; - private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE; - private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS; - private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY; - private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK; - private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION; // How long we wait until we timeout on key dispatching during instrumentation. static final long INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MILLIS = 60 * 1000; @@ -385,6 +363,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { */ final Object mGlobalLockWithoutBoost = mGlobalLock; ActivityTaskSupervisor mTaskSupervisor; + ActivityClientController mActivityClientController; RootWindowContainer mRootWindowContainer; WindowManagerService mWindowManager; private UserManagerService mUserManager; @@ -418,9 +397,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { /** State of external calls telling us if the device is awake or asleep. */ private boolean mKeyguardShown = false; - // Wrapper around VoiceInteractionServiceManager - private AssistUtils mAssistUtils; - // VoiceInteraction session ID that changes for each new request except when // being called for multi-window assist in a single session. private int mViSessionId = 1000; @@ -763,10 +739,10 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { final PackageManager pm = mContext.getPackageManager(); mHasHeavyWeightFeature = pm.hasSystemFeature(FEATURE_CANT_SAVE_STATE); mHasLeanbackFeature = pm.hasSystemFeature(FEATURE_LEANBACK); - mAssistUtils = new AssistUtils(mContext); mVrController.onSystemReady(); mRecentTasks.onSystemReadyLocked(); mTaskSupervisor.onSystemReady(); + mActivityClientController.onSystemReady(); mBlockActivityAfterHomeEnabled = DeviceConfig.getBoolean( DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, BLOCK_ACTIVITY_STARTS_AFTER_HOME_FLAG, false); @@ -872,6 +848,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { mCompatModePackages = new CompatModePackages(this, systemDir, mH); mPendingIntentController = intentController; mTaskSupervisor = createTaskSupervisor(); + mActivityClientController = new ActivityClientController(this); mTaskChangeNotificationController = new TaskChangeNotificationController(mGlobalLock, mTaskSupervisor, mH); @@ -1698,311 +1675,9 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { return mAmInternal.getActivityInfoForUser(aInfo, userId); } - /** - * This is the internal entry point for handling Activity.finish(). - * - * @param token The Binder token referencing the Activity we want to finish. - * @param resultCode Result code, if any, from this Activity. - * @param resultData Result data (Intent), if any, from this Activity. - * @param finishTask Whether to finish the task associated with this Activity. - * @return Returns true if the activity successfully finished, or false if it is still running. - */ - @Override - public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, - int finishTask) { - // Refuse possible leaked file descriptors - if (resultData != null && resultData.hasFileDescriptors()) { - throw new IllegalArgumentException("File descriptors passed in Intent"); - } - - final ActivityRecord r; - synchronized (mGlobalLock) { - r = ActivityRecord.isInStackLocked(token); - if (r == null) { - return true; - } - } - - // Carefully collect grants without holding lock - final NeededUriGrants resultGrants = collectGrants(resultData, r.resultTo); - - synchronized (mGlobalLock) { - // Sanity check in case activity was removed before entering global lock. - if (!r.isInHistory()) { - return true; - } - - // Keep track of the root activity of the task before we finish it - final Task tr = r.getTask(); - final ActivityRecord rootR = tr.getRootActivity(); - if (rootR == null) { - Slog.w(TAG, "Finishing task with all activities already finished"); - } - // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can - // finish. - if (getLockTaskController().activityBlockedFromFinish(r)) { - return false; - } - - // TODO: There is a dup. of this block of code in ActivityStack.navigateUpToLocked - // We should consolidate. - if (mController != null) { - // Find the first activity that is not finishing. - final ActivityRecord next = - r.getRootTask().topRunningActivity(token, INVALID_TASK_ID); - if (next != null) { - // ask watcher if this is allowed - boolean resumeOK = true; - try { - resumeOK = mController.activityResuming(next.packageName); - } catch (RemoteException e) { - mController = null; - Watchdog.getInstance().setActivityController(null); - } - - if (!resumeOK) { - Slog.i(TAG, "Not finishing activity because controller resumed"); - return false; - } - } - } - - // note down that the process has finished an activity and is in background activity - // starts grace period - if (r.app != null) { - r.app.setLastActivityFinishTimeIfNeeded(SystemClock.uptimeMillis()); - } - - final long origId = Binder.clearCallingIdentity(); - Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "finishActivity"); - try { - boolean res; - final boolean finishWithRootActivity = - finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY; - if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY - || (finishWithRootActivity && r == rootR)) { - // If requested, remove the task that is associated to this activity only if it - // was the root activity in the task. The result code and data is ignored - // because we don't support returning them across task boundaries. Also, to - // keep backwards compatibility we remove the task from recents when finishing - // task with root activity. - mTaskSupervisor.removeTask(tr, false /*killProcess*/, - finishWithRootActivity, "finish-activity"); - res = true; - // Explicitly dismissing the activity so reset its relaunch flag. - r.mRelaunchReason = RELAUNCH_REASON_NONE; - } else { - r.finishIfPossible(resultCode, resultData, resultGrants, - "app-request", true /* oomAdj */); - res = r.finishing; - if (!res) { - Slog.i(TAG, "Failed to finish by app-request"); - } - } - return res; - } finally { - Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); - Binder.restoreCallingIdentity(origId); - } - } - } - - @Override - public boolean finishActivityAffinity(IBinder token) { - synchronized (mGlobalLock) { - final long origId = Binder.clearCallingIdentity(); - try { - ActivityRecord r = ActivityRecord.isInStackLocked(token); - if (r == null) { - return false; - } - - // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps - // can finish. - if (getLockTaskController().activityBlockedFromFinish(r)) { - return false; - } - - final PooledFunction p = PooledLambda.obtainFunction( - ActivityRecord::finishIfSameAffinity, r, - PooledLambda.__(ActivityRecord.class)); - r.getTask().forAllActivities( - p, r, true /*includeBoundary*/, true /*traverseTopToBottom*/); - p.recycle(); - - return true; - } finally { - Binder.restoreCallingIdentity(origId); - } - } - } - - @Override - public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { - final long origId = Binder.clearCallingIdentity(); - try { - synchronized (mGlobalLock) { - Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "activityIdle"); - final ActivityRecord r = ActivityRecord.forTokenLocked(token); - if (r == null) { - return; - } - mTaskSupervisor.activityIdleInternal(r, false /* fromTimeout */, - false /* processPausingActivities */, config); - if (stopProfiling && r.hasProcess()) { - r.app.clearProfilerIfNeeded(); - } - } - } finally { - Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); - Binder.restoreCallingIdentity(origId); - } - } - - @Override - public final void activityResumed(IBinder token) { - final long origId = Binder.clearCallingIdentity(); - synchronized (mGlobalLock) { - ActivityRecord.activityResumedLocked(token); - } - Binder.restoreCallingIdentity(origId); - } - - @Override - public final void activityTopResumedStateLost() { - final long origId = Binder.clearCallingIdentity(); - synchronized (mGlobalLock) { - mTaskSupervisor.handleTopResumedStateReleased(false /* timeout */); - } - Binder.restoreCallingIdentity(origId); - } - - @Override - public final void activityPaused(IBinder token) { - final long origId = Binder.clearCallingIdentity(); - synchronized (mGlobalLock) { - Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "activityPaused"); - final ActivityRecord r = ActivityRecord.forTokenLocked(token); - if (r != null) { - r.activityPaused(false); - } - Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); - } - Binder.restoreCallingIdentity(origId); - } - - @Override - public final void activityStopped(IBinder token, Bundle icicle, - PersistableBundle persistentState, CharSequence description) { - if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token); - - // Refuse possible leaked file descriptors - if (icicle != null && icicle.hasFileDescriptors()) { - throw new IllegalArgumentException("File descriptors passed in Bundle"); - } - - final long origId = Binder.clearCallingIdentity(); - - String restartingName = null; - int restartingUid = 0; - final ActivityRecord r; - synchronized (mGlobalLock) { - Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "activityStopped"); - r = ActivityRecord.isInStackLocked(token); - if (r != null) { - if (r.attachedToProcess() - && r.isState(Task.ActivityState.RESTARTING_PROCESS)) { - // The activity was requested to restart from - // {@link #restartActivityProcessIfVisible}. - restartingName = r.app.mName; - restartingUid = r.app.mUid; - } - r.activityStopped(icicle, persistentState, description); - } - Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); - } - - if (restartingName != null) { - // In order to let the foreground activity can be restarted with its saved state from - // {@link android.app.Activity#onSaveInstanceState}, the kill operation is postponed - // until the activity reports stopped with the state. And the activity record will be - // kept because the record state is restarting, then the activity will be restarted - // immediately if it is still the top one. - mTaskSupervisor.removeRestartTimeouts(r); - mAmInternal.killProcess(restartingName, restartingUid, "restartActivityProcess"); - } - mAmInternal.trimApplications(); - - Binder.restoreCallingIdentity(origId); - } - - @Override - public final void activityDestroyed(IBinder token) { - if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token); - synchronized (mGlobalLock) { - final long origId = Binder.clearCallingIdentity(); - Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "activityDestroyed"); - try { - final ActivityRecord activity = ActivityRecord.forTokenLocked(token); - if (activity != null) { - activity.destroyed("activityDestroyed"); - } - } finally { - Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); - Binder.restoreCallingIdentity(origId); - } - } - } - - @Override - public final void activityRelaunched(IBinder token) { - final long origId = Binder.clearCallingIdentity(); - synchronized (mGlobalLock) { - mTaskSupervisor.activityRelaunchedLocked(token); - } - Binder.restoreCallingIdentity(origId); - } - @Override - public void setRequestedOrientation(IBinder token, int requestedOrientation) { - synchronized (mGlobalLock) { - ActivityRecord r = ActivityRecord.isInStackLocked(token); - if (r == null) { - return; - } - final long origId = Binder.clearCallingIdentity(); - try { - r.setRequestedOrientation(requestedOrientation); - } finally { - Binder.restoreCallingIdentity(origId); - } - } - } - - @Override - public int getRequestedOrientation(IBinder token) { - synchronized (mGlobalLock) { - final ActivityRecord r = ActivityRecord.isInStackLocked(token); - return (r != null) - ? r.getRequestedOrientation() : ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; - } - } - - @Override - public void setImmersive(IBinder token, boolean immersive) { - synchronized (mGlobalLock) { - final ActivityRecord r = ActivityRecord.isInStackLocked(token); - if (r == null) { - throw new IllegalArgumentException(); - } - r.immersive = immersive; - - // update associated state if we're frontmost - if (r.isFocusedActivityOnDisplay()) { - ProtoLog.d(WM_DEBUG_IMMERSIVE, "Frontmost changed immersion: %s", r); - applyUpdateLockStateLocked(r); - } - } + public IActivityClientController getActivityClientController() { + return mActivityClientController; } void applyUpdateLockStateLocked(ActivityRecord r) { @@ -2025,17 +1700,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } @Override - public boolean isImmersive(IBinder token) { - synchronized (mGlobalLock) { - final ActivityRecord r = ActivityRecord.isInStackLocked(token); - if (r == null) { - throw new IllegalArgumentException(); - } - return r.immersive; - } - } - - @Override public boolean isTopActivityImmersive() { enforceNotIsolatedCaller("isTopActivityImmersive"); synchronized (mGlobalLock) { @@ -2050,27 +1714,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } @Override - public void overridePendingTransition(IBinder token, String packageName, - int enterAnim, int exitAnim) { - synchronized (mGlobalLock) { - ActivityRecord self = ActivityRecord.isInStackLocked(token); - if (self == null) { - return; - } - - final long origId = Binder.clearCallingIdentity(); - - if (self.isState( - Task.ActivityState.RESUMED, Task.ActivityState.PAUSING)) { - self.mDisplayContent.mAppTransition.overridePendingAppTransition( - packageName, enterAnim, exitAnim, null, null); - } - - Binder.restoreCallingIdentity(origId); - } - } - - @Override public int getFrontActivityScreenCompatMode() { enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); synchronized (mGlobalLock) { @@ -2125,77 +1768,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } @Override - public boolean convertFromTranslucent(IBinder token) { - final long origId = Binder.clearCallingIdentity(); - try { - synchronized (mGlobalLock) { - final ActivityRecord r = ActivityRecord.isInStackLocked(token); - if (r == null) { - return false; - } - return r.setOccludesParent(true); - } - } finally { - Binder.restoreCallingIdentity(origId); - } - } - - @Override - public boolean convertToTranslucent(IBinder token, Bundle options) { - SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(options); - final long origId = Binder.clearCallingIdentity(); - try { - synchronized (mGlobalLock) { - final ActivityRecord r = ActivityRecord.isInStackLocked(token); - if (r == null) { - return false; - } - final ActivityRecord under = r.getTask().getActivityBelow(r); - if (under != null) { - under.returningOptions = safeOptions != null ? safeOptions.getOptions(r) : null; - } - return r.setOccludesParent(false); - } - } finally { - Binder.restoreCallingIdentity(origId); - } - } - - @Override - public void notifyActivityDrawn(IBinder token) { - if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token); - synchronized (mGlobalLock) { - ActivityRecord r = mRootWindowContainer.isInAnyTask(token); - if (r != null) { - r.getRootTask().notifyActivityDrawnLocked(r); - } - } - } - - @Override - public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) { - synchronized (mGlobalLock) { - ActivityRecord r = ActivityRecord.isInStackLocked(token); - if (r == null) { - return; - } - r.reportFullyDrawnLocked(restoredFromBundle); - } - } - - @Override - public int getDisplayId(IBinder activityToken) throws RemoteException { - synchronized (mGlobalLock) { - final Task stack = ActivityRecord.getStackLocked(activityToken); - if (stack != null) { - final int displayId = stack.getDisplayId(); - return displayId != INVALID_DISPLAY ? displayId : DEFAULT_DISPLAY; - } - return DEFAULT_DISPLAY; - } - } - - @Override public RootTaskInfo getFocusedRootTaskInfo() throws RemoteException { enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_TASKS, "getFocusedRootTaskInfo()"); final long ident = Binder.clearCallingIdentity(); @@ -2312,75 +1884,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } @Override - public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { - synchronized (mGlobalLock) { - final ActivityRecord srec = ActivityRecord.forTokenLocked(token); - if (srec != null) { - return srec.getRootTask().shouldUpRecreateTaskLocked(srec, destAffinity); - } - } - return false; - } - - @Override - public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, - Intent resultData) { - final ActivityRecord r; - synchronized (mGlobalLock) { - r = ActivityRecord.isInStackLocked(token); - if (r == null) { - return false; - } - } - - // Carefully collect grants without holding lock - final NeededUriGrants destGrants = collectGrants(destIntent, r); - final NeededUriGrants resultGrants = collectGrants(resultData, r.resultTo); - - synchronized (mGlobalLock) { - return r.getRootTask().navigateUpTo( - r, destIntent, destGrants, resultCode, resultData, resultGrants); - } - } - - /** - * Attempts to move a task backwards in z-order (the order of activities within the task is - * unchanged). - * - * There are several possible results of this call: - * - if the task is locked, then we will show the lock toast - * - if there is a task behind the provided task, then that task is made visible and resumed as - * this task is moved to the back - * - otherwise, if there are no other tasks in the stack: - * - if this task is in the pinned stack, then we remove the stack completely, which will - * have the effect of moving the task to the top or bottom of the fullscreen stack - * (depending on whether it is visible) - * - otherwise, we simply return home and hide this task - * - * @param token A reference to the activity we wish to move - * @param nonRoot If false then this only works if the activity is the root - * of a task; if true it will work for any activity in a task. - * @return Returns true if the move completed, false if not. - */ - @Override - public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { - enforceNotIsolatedCaller("moveActivityTaskToBack"); - synchronized (mGlobalLock) { - final long origId = Binder.clearCallingIdentity(); - try { - int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); - final Task task = mRootWindowContainer.anyTaskForId(taskId); - if (task != null) { - return ActivityRecord.getStackLocked(token).moveTaskToBack(task); - } - } finally { - Binder.restoreCallingIdentity(origId); - } - } - return false; - } - - @Override public Rect getTaskBounds(int taskId) { enforceTaskPermission("getTaskBounds()"); final long ident = Binder.clearCallingIdentity(); @@ -2467,31 +1970,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } } - @Override - public String getCallingPackage(IBinder token) { - synchronized (mGlobalLock) { - ActivityRecord r = getCallingRecordLocked(token); - return r != null ? r.info.packageName : null; - } - } - - @Override - public ComponentName getCallingActivity(IBinder token) { - synchronized (mGlobalLock) { - ActivityRecord r = getCallingRecordLocked(token); - return r != null ? r.intent.getComponent() : null; - } - } - - private ActivityRecord getCallingRecordLocked(IBinder token) { - ActivityRecord r = ActivityRecord.isInStackLocked(token); - if (r == null) { - return null; - } - return r.resultTo; - } - - private NeededUriGrants collectGrants(Intent intent, ActivityRecord target) { + NeededUriGrants collectGrants(Intent intent, ActivityRecord target) { if (target != null) { return mUgmInternal.checkGrantUriPermissionFromIntent(intent, Binder.getCallingUid(), target.packageName, target.mUserId); @@ -2518,25 +1997,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } } - @Override - public void onBackPressedOnTaskRoot(IBinder token) { - synchronized (mGlobalLock) { - ActivityRecord r = ActivityRecord.isInStackLocked(token); - if (r == null) { - return; - } - Task stack = r.getRootTask(); - final TaskOrganizerController taskOrgController = - mWindowOrganizerController.mTaskOrganizerController; - if (taskOrgController.handleInterceptBackPressedOnTaskRoot(stack)) { - // This task is handled by a task organizer that has requested the back pressed - // callback - } else { - moveActivityTaskToBack(token, false /* nonRoot */); - } - } - } - /** * TODO: Add mController hook */ @@ -2731,13 +2191,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } } - @Override - public int getTaskForActivity(IBinder token, boolean onlyRoot) { - synchronized (mGlobalLock) { - return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); - } - } - List<ActivityManager.RunningTaskInfo> getTasks(int maxNum) { return getTasks(maxNum, false /* filterForVisibleRecents */); } @@ -2772,40 +2225,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } @Override - public final void finishSubActivity(IBinder token, String resultWho, int requestCode) { - synchronized (mGlobalLock) { - final long origId = Binder.clearCallingIdentity(); - try { - ActivityRecord r = ActivityRecord.isInStackLocked(token); - if (r == null) return; - - final PooledConsumer c = PooledLambda.obtainConsumer( - ActivityRecord::finishIfSubActivity, PooledLambda.__(ActivityRecord.class), - r, resultWho, requestCode); - // TODO: This should probably only loop over the task since you need to be in the - // same task to return results. - r.getRootTask().forAllActivities(c); - c.recycle(); - - updateOomAdj(); - } finally { - Binder.restoreCallingIdentity(origId); - } - } - } - - @Override - public boolean willActivityBeVisible(IBinder token) { - synchronized (mGlobalLock) { - Task stack = ActivityRecord.getStackLocked(token); - if (stack != null) { - return stack.willActivityBeVisible(token); - } - return false; - } - } - - @Override public void moveTaskToRootTask(int taskId, int rootTaskId, boolean toTop) { enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_TASKS, "moveTaskToRootTask()"); synchronized (mGlobalLock) { @@ -3035,17 +2454,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } @Override - public void startLockTaskModeByToken(IBinder token) { - synchronized (mGlobalLock) { - final ActivityRecord r = ActivityRecord.forTokenLocked(token); - if (r == null) { - return; - } - startLockTaskModeLocked(r.getTask(), false /* isSystemCaller */); - } - } - - @Override public void startSystemLockTaskMode(int taskId) { enforceTaskPermission("startSystemLockTaskMode"); // This makes inner call to look as if it was initiated by system. @@ -3060,18 +2468,13 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { // When starting lock task mode the stack must be in front and focused task.getRootTask().moveToFront("startSystemLockTaskMode"); - startLockTaskModeLocked(task, true /* isSystemCaller */); + startLockTaskMode(task, true /* isSystemCaller */); } } finally { Binder.restoreCallingIdentity(ident); } } - @Override - public void stopLockTaskModeByToken(IBinder token) { - stopLockTaskModeInternal(token, false /* isSystemCaller */); - } - /** * This API should be called by SystemUI only when user perform certain action to dismiss * lock task mode. We should only dismiss pinned lock task mode in this case. @@ -3082,8 +2485,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { stopLockTaskModeInternal(null, true /* isSystemCaller */); } - private void startLockTaskModeLocked(@Nullable Task task, boolean isSystemCaller) { - ProtoLog.w(WM_DEBUG_LOCKTASK, "startLockTaskModeLocked: %s", task); + void startLockTaskMode(@Nullable Task task, boolean isSystemCaller) { + ProtoLog.w(WM_DEBUG_LOCKTASK, "startLockTaskMode: %s", task); if (task == null || task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) { return; } @@ -3111,7 +2514,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } } - private void stopLockTaskModeInternal(@Nullable IBinder token, boolean isSystemCaller) { + void stopLockTaskModeInternal(@Nullable IBinder token, boolean isSystemCaller) { final int callingUid = Binder.getCallingUid(); final long ident = Binder.clearCallingIdentity(); try { @@ -3163,34 +2566,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } @Override - public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { - synchronized (mGlobalLock) { - ActivityRecord r = ActivityRecord.isInStackLocked(token); - if (r != null) { - r.setTaskDescription(td); - } - } - } - - @Override - public Bundle getActivityOptions(IBinder token) { - final long origId = Binder.clearCallingIdentity(); - try { - synchronized (mGlobalLock) { - final ActivityRecord r = ActivityRecord.isInStackLocked(token); - if (r != null) { - final ActivityOptions activityOptions = r.takeOptionsLocked( - true /* fromClient */); - return activityOptions == null ? null : activityOptions.toBundle(); - } - return null; - } - } finally { - Binder.restoreCallingIdentity(origId); - } - } - - @Override public List<IBinder> getAppTasks(String callingPackage) { int callingUid = Binder.getCallingUid(); assertPackageMatchesCallingUid(callingPackage); @@ -3220,39 +2595,9 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } @Override - public boolean isTopOfTask(IBinder token) { - synchronized (mGlobalLock) { - ActivityRecord r = ActivityRecord.isInStackLocked(token); - return r != null && r.getTask().getTopNonFinishingActivity() == r; - } - } - - @Override - public void notifyLaunchTaskBehindComplete(IBinder token) { - mTaskSupervisor.scheduleLaunchTaskBehindComplete(token); - } - - @Override - public void notifyEnterAnimationComplete(IBinder token) { - mH.post(() -> { - synchronized (mGlobalLock) { - ActivityRecord r = ActivityRecord.forTokenLocked(token); - if (r != null && r.attachedToProcess()) { - try { - r.app.getThread().scheduleEnterAnimationComplete(r.appToken); - } catch (RemoteException e) { - } - } - } - - }); - } - - /** Called from an app when assist data is ready. */ - @Override - public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure, - AssistContent content, Uri referrer) { - PendingAssistExtras pae = (PendingAssistExtras) token; + public void reportAssistContextExtras(IBinder assistToken, Bundle extras, + AssistStructure structure, AssistContent content, Uri referrer) { + final PendingAssistExtras pae = (PendingAssistExtras) assistToken; synchronized (pae) { pae.result = extras; pae.structure = structure; @@ -3440,23 +2785,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } @Override - public boolean releaseActivityInstance(IBinder token) { - synchronized (mGlobalLock) { - final long origId = Binder.clearCallingIdentity(); - try { - final ActivityRecord r = ActivityRecord.isInStackLocked(token); - if (r == null || !r.isDestroyable()) { - return false; - } - r.destroyImmediately("app-req"); - return r.isState(DESTROYING, DESTROYED); - } finally { - Binder.restoreCallingIdentity(origId); - } - } - } - - @Override public void releaseSomeActivities(IApplicationThread appInt) { synchronized (mGlobalLock) { final long origId = Binder.clearCallingIdentity(); @@ -3540,49 +2868,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } } - @Override - public void toggleFreeformWindowingMode(IBinder token) { - synchronized (mGlobalLock) { - final long ident = Binder.clearCallingIdentity(); - try { - final ActivityRecord r = ActivityRecord.forTokenLocked(token); - if (r == null) { - throw new IllegalArgumentException( - "toggleFreeformWindowingMode: No activity record matching token=" - + token); - } - - final Task stack = r.getRootTask(); - if (stack == null) { - throw new IllegalStateException("toggleFreeformWindowingMode: the activity " - + "doesn't have a stack"); - } - - if (!stack.inFreeformWindowingMode() - && stack.getWindowingMode() != WINDOWING_MODE_FULLSCREEN) { - throw new IllegalStateException("toggleFreeformWindowingMode: You can only " - + "toggle between fullscreen and freeform."); - } - - if (stack.inFreeformWindowingMode()) { - stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN); - } else if (!mSizeCompatFreeform && r.inSizeCompatMode()) { - throw new IllegalStateException("Size-compat windows are currently not" - + "freeform-enabled"); - } else if (stack.getParent().inFreeformWindowingMode()) { - // If the window is on a freeform display, set it to undefined. It will be - // resolved to freeform and it can adjust windowing mode when the display mode - // changes in runtime. - stack.setWindowingMode(WINDOWING_MODE_UNDEFINED); - } else { - stack.setWindowingMode(WINDOWING_MODE_FREEFORM); - } - } finally { - Binder.restoreCallingIdentity(ident); - } - } - } - /** Sets the task stack listener that gets callbacks when a task stack changes. */ @Override public void registerTaskStackListener(ITaskStackListener listener) { @@ -3884,42 +3169,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { return DevicePolicyCache.getInstance().isScreenCaptureAllowed(userId, false); } - @Override - public boolean showAssistFromActivity(IBinder token, Bundle args) { - final long ident = Binder.clearCallingIdentity(); - try { - synchronized (mGlobalLock) { - ActivityRecord caller = ActivityRecord.forTokenLocked(token); - ActivityRecord top = getTopDisplayFocusedRootTask().getTopNonFinishingActivity(); - if (top != caller) { - Slog.w(TAG, "showAssistFromActivity failed: caller " + caller - + " is not current top " + top); - return false; - } - if (!top.nowVisible) { - Slog.w(TAG, "showAssistFromActivity failed: caller " + caller - + " is not visible"); - return false; - } - } - return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null, - token); - } finally { - Binder.restoreCallingIdentity(ident); - } - } - - @Override - public boolean isRootVoiceInteraction(IBinder token) { - synchronized (mGlobalLock) { - ActivityRecord r = ActivityRecord.isInStackLocked(token); - if (r == null) { - return false; - } - return r.rootVoiceInteraction; - } - } - private void onLocalVoiceInteractionStartedLocked(IBinder activity, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) { ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity); @@ -4001,17 +3250,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } @Override - public void showLockTaskEscapeMessage(IBinder token) { - synchronized (mGlobalLock) { - final ActivityRecord r = ActivityRecord.forTokenLocked(token); - if (r == null) { - return; - } - getLockTaskController().showLockTaskToast(); - } - } - - @Override public void keyguardGoingAway(int flags) { enforceNotIsolatedCaller("keyguardGoingAway"); final long token = Binder.clearCallingIdentity(); @@ -4025,22 +3263,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } @Override - public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration, - int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) { - ProtoLog.v(WM_DEBUG_CONFIGURATION, "Report configuration: %s %s %s", - token, Arrays.toString(horizontalSizeConfiguration), - Arrays.toString(verticalSizeConfigurations)); - synchronized (mGlobalLock) { - ActivityRecord record = ActivityRecord.isInStackLocked(token); - if (record == null) { - return; - } - record.setSizeConfigurations(horizontalSizeConfiguration, - verticalSizeConfigurations, smallestSizeConfigurations); - } - } - - @Override public void suppressResizeConfigChanges(boolean suppress) throws RemoteException { mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_TASKS, "suppressResizeConfigChanges()"); @@ -4138,100 +3360,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { return true; } - @Override - public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) { - final long origId = Binder.clearCallingIdentity(); - try { - synchronized (mGlobalLock) { - final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked( - "enterPictureInPictureMode", token, params); - return enterPictureInPictureMode(r, params); - } - } finally { - Binder.restoreCallingIdentity(origId); - } - } - - @Override - public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) { - final long origId = Binder.clearCallingIdentity(); - try { - synchronized (mGlobalLock) { - final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked( - "setPictureInPictureParams", token, params); - - // Only update the saved args from the args that are set - r.setPictureInPictureParams(params); - if (r.inPinnedWindowingMode()) { - // If the activity is already in picture-in-picture, update the pinned stack now - // if it is not already expanding to fullscreen. Otherwise, the arguments will - // be used the next time the activity enters PiP - final Task stack = r.getRootTask(); - stack.setPictureInPictureAspectRatio( - r.pictureInPictureArgs.getAspectRatio()); - stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions()); - } - } - } finally { - Binder.restoreCallingIdentity(origId); - } - } - - /** - * Checks the state of the system and the activity associated with the given {@param token} to - * verify that picture-in-picture is supported for that activity. - * - * @return the activity record for the given {@param token} if all the checks pass. - */ - private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller, - IBinder token, PictureInPictureParams params) { - if (!mSupportsPictureInPicture) { - throw new IllegalStateException(caller - + ": Device doesn't support picture-in-picture mode."); - } - - final ActivityRecord r = ActivityRecord.forTokenLocked(token); - if (r == null) { - throw new IllegalStateException(caller - + ": Can't find activity for token=" + token); - } - - if (!r.supportsPictureInPicture()) { - throw new IllegalStateException(caller - + ": Current activity does not support picture-in-picture."); - } - - if (params.hasSetAspectRatio() - && !mWindowManager.isValidPictureInPictureAspectRatio( - r.mDisplayContent, params.getAspectRatio())) { - final float minAspectRatio = mContext.getResources().getFloat( - com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio); - final float maxAspectRatio = mContext.getResources().getFloat( - com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio); - throw new IllegalArgumentException(String.format(caller - + ": Aspect ratio is too extreme (must be between %f and %f).", - minAspectRatio, maxAspectRatio)); - } - - // Truncate the number of actions if necessary - params.truncateActions(ActivityTaskManager.getMaxNumPictureInPictureActions(mContext)); - - return r; - } - - @Override - public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) { - enforceNotIsolatedCaller("getUriPermissionOwnerForActivity"); - synchronized (mGlobalLock) { - ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); - if (r == null) { - throw new IllegalArgumentException("Activity does not exist; token=" - + activityToken); - } - return r.getUriPermissionsLocked().getExternalToken(); - } - } - // TODO(b/149338177): remove when CTS no-longer requires it @Override public void resizePrimarySplitScreen(Rect dockedBounds, Rect tempDockedTaskBounds, @@ -4304,73 +3432,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } @Override - public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) { - enforceSystemHasVrFeature(); - - final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class); - - ActivityRecord r; - synchronized (mGlobalLock) { - r = ActivityRecord.isInStackLocked(token); - } - - if (r == null) { - throw new IllegalArgumentException(); - } - - int err; - if ((err = vrService.hasVrPackage(packageName, r.mUserId)) != - VrManagerInternal.NO_ERROR) { - return err; - } - - // Clear the binder calling uid since this path may call moveToTask(). - final long callingId = Binder.clearCallingIdentity(); - try { - synchronized (mGlobalLock) { - r.requestedVrComponent = (enabled) ? packageName : null; - - // Update associated state if this activity is currently focused - if (r.isFocusedActivityOnDisplay()) { - applyUpdateVrModeLocked(r); - } - return 0; - } - } finally { - Binder.restoreCallingIdentity(callingId); - } - } - - @Override - public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options) { - Slog.i(TAG, "Activity tried to startLocalVoiceInteraction"); - synchronized (mGlobalLock) { - ActivityRecord activity = getTopDisplayFocusedRootTask().getTopNonFinishingActivity(); - if (ActivityRecord.forTokenLocked(callingActivity) != activity) { - throw new SecurityException("Only focused activity can call startVoiceInteraction"); - } - if (mRunningVoice != null || activity.getTask().voiceSession != null - || activity.voiceSession != null) { - Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction"); - return; - } - if (activity.pendingVoiceInteractionStart) { - Slog.w(TAG, "Pending start of voice interaction already."); - return; - } - activity.pendingVoiceInteractionStart = true; - } - LocalServices.getService(VoiceInteractionManagerInternal.class) - .startLocalVoiceInteraction(callingActivity, options); - } - - @Override - public void stopLocalVoiceInteraction(IBinder callingActivity) { - LocalServices.getService(VoiceInteractionManagerInternal.class) - .stopLocalVoiceInteraction(callingActivity); - } - - @Override public boolean supportsLocalVoiceInteraction() { return LocalServices.getService(VoiceInteractionManagerInternal.class) .supportsLocalVoiceInteraction(); @@ -4474,24 +3535,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } @Override - public void setDisablePreviewScreenshots(IBinder token, boolean disable) { - synchronized (mGlobalLock) { - final ActivityRecord r = ActivityRecord.isInStackLocked(token); - if (r == null) { - Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token=" - + token); - return; - } - final long origId = Binder.clearCallingIdentity(); - try { - r.setDisablePreviewScreenshots(disable); - } finally { - Binder.restoreCallingIdentity(origId); - } - } - } - - @Override public void invalidateHomeTaskSnapshot(IBinder token) { synchronized (mGlobalLock) { final ActivityRecord r = ActivityRecord.isInStackLocked(token); @@ -4532,91 +3575,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } @Override - public void setShowWhenLocked(IBinder token, boolean showWhenLocked) { - synchronized (mGlobalLock) { - final ActivityRecord r = ActivityRecord.isInStackLocked(token); - if (r == null) { - return; - } - final long origId = Binder.clearCallingIdentity(); - try { - r.setShowWhenLocked(showWhenLocked); - } finally { - Binder.restoreCallingIdentity(origId); - } - } - } - - @Override - public void setInheritShowWhenLocked(IBinder token, boolean inheritShowWhenLocked) { - synchronized (mGlobalLock) { - final ActivityRecord r = ActivityRecord.isInStackLocked(token); - if (r == null) { - return; - } - final long origId = Binder.clearCallingIdentity(); - try { - r.setInheritShowWhenLocked(inheritShowWhenLocked); - } finally { - Binder.restoreCallingIdentity(origId); - } - } - } - - @Override - public void setTurnScreenOn(IBinder token, boolean turnScreenOn) { - synchronized (mGlobalLock) { - final ActivityRecord r = ActivityRecord.isInStackLocked(token); - if (r == null) { - return; - } - final long origId = Binder.clearCallingIdentity(); - try { - r.setTurnScreenOn(turnScreenOn); - } finally { - Binder.restoreCallingIdentity(origId); - } - } - } - - @Override - public void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition) { - mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS, - "registerRemoteAnimations"); - definition.setCallingPidUid(Binder.getCallingPid(), Binder.getCallingUid()); - synchronized (mGlobalLock) { - final ActivityRecord r = ActivityRecord.isInStackLocked(token); - if (r == null) { - return; - } - final long origId = Binder.clearCallingIdentity(); - try { - r.registerRemoteAnimations(definition); - } finally { - Binder.restoreCallingIdentity(origId); - } - } - } - - @Override - public void unregisterRemoteAnimations(IBinder token) { - mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS, - "unregisterRemoteAnimations"); - synchronized (mGlobalLock) { - final ActivityRecord r = ActivityRecord.isInStackLocked(token); - if (r == null) { - return; - } - final long origId = Binder.clearCallingIdentity(); - try { - r.unregisterRemoteAnimations(); - } finally { - Binder.restoreCallingIdentity(origId); - } - } - } - - @Override public void registerRemoteAnimationForNextActivityStart(String packageName, RemoteAnimationAdapter adapter) { mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS, @@ -4743,7 +3701,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { return mVrController.shouldDisableNonVrUiLocked(); } - private void applyUpdateVrModeLocked(ActivityRecord r) { + void applyUpdateVrModeLocked(ActivityRecord r) { // VR apps are expected to run in a main display. If an app is turning on VR for // itself, but isn't on the main display, then move it there before enabling VR Mode. if (r.requestedVrComponent != null && r.getDisplayId() != DEFAULT_DISPLAY) { @@ -5097,7 +4055,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { return mAmInternal.getCurrentUserId(); } - private void enforceNotIsolatedCaller(String caller) { + static void enforceNotIsolatedCaller(String caller) { if (UserHandle.isIsolated(Binder.getCallingUid())) { throw new SecurityException("Isolated process not allowed to call " + caller); } diff --git a/services/core/java/com/android/server/wm/DragAndDropPermissionsHandler.java b/services/core/java/com/android/server/wm/DragAndDropPermissionsHandler.java index 14880ed30f24..9602880486b5 100644 --- a/services/core/java/com/android/server/wm/DragAndDropPermissionsHandler.java +++ b/services/core/java/com/android/server/wm/DragAndDropPermissionsHandler.java @@ -16,7 +16,6 @@ package com.android.server.wm; -import android.app.ActivityTaskManager; import android.app.UriGrantsManager; import android.content.ClipData; import android.net.Uri; @@ -33,6 +32,7 @@ import java.util.ArrayList; class DragAndDropPermissionsHandler extends IDragAndDropPermissions.Stub implements IBinder.DeathRecipient { + private final WindowManagerGlobalLock mGlobalLock; private final int mSourceUid; private final String mTargetPackage; private final int mMode; @@ -45,8 +45,9 @@ class DragAndDropPermissionsHandler extends IDragAndDropPermissions.Stub private IBinder mPermissionOwnerToken = null; private IBinder mTransientToken = null; - DragAndDropPermissionsHandler(ClipData clipData, int sourceUid, String targetPackage, int mode, - int sourceUserId, int targetUserId) { + DragAndDropPermissionsHandler(WindowManagerGlobalLock lock, ClipData clipData, int sourceUid, + String targetPackage, int mode, int sourceUserId, int targetUserId) { + mGlobalLock = lock; mSourceUid = sourceUid; mTargetPackage = targetPackage; mMode = mode; @@ -64,8 +65,7 @@ class DragAndDropPermissionsHandler extends IDragAndDropPermissions.Stub mActivityToken = activityToken; // Will throw if Activity is not found. - IBinder permissionOwner = ActivityTaskManager.getService(). - getUriPermissionOwnerForActivity(mActivityToken); + IBinder permissionOwner = getUriPermissionOwnerForActivity(mActivityToken); doTake(permissionOwner); } @@ -105,8 +105,7 @@ class DragAndDropPermissionsHandler extends IDragAndDropPermissions.Stub IBinder permissionOwner = null; if (mActivityToken != null) { try { - permissionOwner = ActivityTaskManager.getService(). - getUriPermissionOwnerForActivity(mActivityToken); + permissionOwner = getUriPermissionOwnerForActivity(mActivityToken); } catch (Exception e) { // Activity is destroyed, permissions already revoked. return; @@ -126,6 +125,18 @@ class DragAndDropPermissionsHandler extends IDragAndDropPermissions.Stub } } + private IBinder getUriPermissionOwnerForActivity(IBinder activityToken) { + ActivityTaskManagerService.enforceNotIsolatedCaller("getUriPermissionOwnerForActivity"); + synchronized (mGlobalLock) { + ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); + if (r == null) { + throw new IllegalArgumentException("Activity does not exist; token=" + + activityToken); + } + return r.getUriPermissionsLocked().getExternalToken(); + } + } + @Override public void binderDied() { try { diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java index ad4e64a08183..86518ea4ccc1 100644 --- a/services/core/java/com/android/server/wm/DragState.java +++ b/services/core/java/com/android/server/wm/DragState.java @@ -59,7 +59,6 @@ import android.view.WindowManager; import android.view.animation.DecelerateInterpolator; import android.view.animation.Interpolator; -import com.android.internal.os.SomeArgs; import com.android.internal.protolog.common.ProtoLog; import com.android.internal.view.IDragAndDropPermissions; import com.android.server.LocalServices; @@ -590,7 +589,7 @@ class DragState { final DragAndDropPermissionsHandler dragAndDropPermissions; if ((mFlags & View.DRAG_FLAG_GLOBAL) != 0 && (mFlags & DRAG_FLAGS_URI_ACCESS) != 0 && mData != null) { - dragAndDropPermissions = new DragAndDropPermissionsHandler( + dragAndDropPermissions = new DragAndDropPermissionsHandler(mService.mGlobalLock, mData, mUid, touchedWin.getOwningPackage(), diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index d4efa8a7ab91..7c290c465c32 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -1121,10 +1121,7 @@ public class WindowManagerService extends IWindowManager.Stub final boolean isRecentsAnimationTarget = getRecentsAnimationController() != null && getRecentsAnimationController().isTargetApp(atoken); if (atoken.mLaunchTaskBehind && !isRecentsAnimationTarget) { - try { - mActivityTaskManager.notifyLaunchTaskBehindComplete(atoken.token); - } catch (RemoteException e) { - } + mAtmService.mTaskSupervisor.scheduleLaunchTaskBehindComplete(atoken.token); atoken.mLaunchTaskBehind = false; } else { atoken.updateReportedVisibilityLocked(); @@ -1132,9 +1129,11 @@ public class WindowManagerService extends IWindowManager.Stub // successfully finishes. if (atoken.mEnteringAnimation && !isRecentsAnimationTarget) { atoken.mEnteringAnimation = false; - try { - mActivityTaskManager.notifyEnterAnimationComplete(atoken.token); - } catch (RemoteException e) { + if (atoken != null && atoken.attachedToProcess()) { + try { + atoken.app.getThread().scheduleEnterAnimationComplete(atoken.appToken); + } catch (RemoteException e) { + } } } } @@ -5108,9 +5107,11 @@ public class WindowManagerService extends IWindowManager.Stub } case NOTIFY_ACTIVITY_DRAWN: { - try { - mActivityTaskManager.notifyActivityDrawn((IBinder) msg.obj); - } catch (RemoteException e) { + final ActivityRecord activity = (ActivityRecord) msg.obj; + synchronized (mGlobalLock) { + if (activity.isAttached()) { + activity.getRootTask().notifyActivityDrawnLocked(activity); + } } break; } diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java index 3d31824e5aae..080f04efa9b4 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java @@ -80,13 +80,13 @@ public class ActivityTaskManagerServiceTests extends WindowTestsBase { public void testActivityFinish() { final Task stack = new TaskBuilder(mSupervisor).setCreateActivity(true).build(); final ActivityRecord activity = stack.getBottomMostTask().getTopNonFinishingActivity(); - assertTrue("Activity must be finished", mAtm.finishActivity(activity.appToken, - 0 /* resultCode */, null /* resultData */, + assertTrue("Activity must be finished", mAtm.mActivityClientController.finishActivity( + activity.appToken, 0 /* resultCode */, null /* resultData */, Activity.DONT_FINISH_TASK_WITH_ACTIVITY)); assertTrue(activity.finishing); assertTrue("Duplicate activity finish request must also return 'true'", - mAtm.finishActivity(activity.appToken, 0 /* resultCode */, + mAtm.mActivityClientController.finishActivity(activity.appToken, 0 /* resultCode */, null /* resultData */, Activity.DONT_FINISH_TASK_WITH_ACTIVITY)); } @@ -225,7 +225,7 @@ public class ActivityTaskManagerServiceTests extends WindowTestsBase { //to simulate NPE doReturn(null).when(record).getParent(); - mAtm.enterPictureInPictureMode(token, params); + mAtm.mActivityClientController.enterPictureInPictureMode(token, params); //if record's null parent is not handled gracefully, test will fail with NPE mockSession.finishMocking(); diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java index dba157e6ce06..f123bc16e52c 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java @@ -824,7 +824,8 @@ public class WindowOrganizerTests extends WindowTestsBase { final PictureInPictureParams p = new PictureInPictureParams.Builder() .setAspectRatio(new Rational(1, 2)).build(); - assertTrue(mWm.mAtmService.enterPictureInPictureMode(record.token, p)); + assertTrue(mWm.mAtmService.mActivityClientController.enterPictureInPictureMode( + record.token, p)); waitUntilHandlersIdle(); assertNotNull(o.mInfo); assertNotNull(o.mInfo.pictureInPictureParams); @@ -845,14 +846,15 @@ public class WindowOrganizerTests extends WindowTestsBase { final ActivityRecord record = makePipableActivity(); final PictureInPictureParams p = new PictureInPictureParams.Builder() .setAspectRatio(new Rational(1, 2)).build(); - assertTrue(mWm.mAtmService.enterPictureInPictureMode(record.token, p)); + assertTrue(mWm.mAtmService.mActivityClientController.enterPictureInPictureMode( + record.token, p)); waitUntilHandlersIdle(); assertNotNull(o.mInfo); assertNotNull(o.mInfo.pictureInPictureParams); final PictureInPictureParams p2 = new PictureInPictureParams.Builder() .setAspectRatio(new Rational(3, 4)).build(); - mWm.mAtmService.setPictureInPictureParams(record.token, p2); + mWm.mAtmService.mActivityClientController.setPictureInPictureParams(record.token, p2); waitUntilHandlersIdle(); assertNotNull(o.mChangedInfo); assertNotNull(o.mChangedInfo.pictureInPictureParams); @@ -920,7 +922,7 @@ public class WindowOrganizerTests extends WindowTestsBase { assertTrue(stack2.isOrganized()); // Verify a back pressed does not call the organizer - mWm.mAtmService.onBackPressedOnTaskRoot(activity.token); + mWm.mAtmService.mActivityClientController.onBackPressedOnTaskRoot(activity.token); verify(organizer, never()).onBackPressedOnTaskRoot(any()); // Enable intercepting back @@ -928,7 +930,7 @@ public class WindowOrganizerTests extends WindowTestsBase { stack.mRemoteToken.toWindowContainerToken(), true); // Verify now that the back press does call the organizer - mWm.mAtmService.onBackPressedOnTaskRoot(activity.token); + mWm.mAtmService.mActivityClientController.onBackPressedOnTaskRoot(activity.token); verify(organizer, times(1)).onBackPressedOnTaskRoot(any()); // Disable intercepting back @@ -936,7 +938,7 @@ public class WindowOrganizerTests extends WindowTestsBase { stack.mRemoteToken.toWindowContainerToken(), false); // Verify now that the back press no longer calls the organizer - mWm.mAtmService.onBackPressedOnTaskRoot(activity.token); + mWm.mAtmService.mActivityClientController.onBackPressedOnTaskRoot(activity.token); verify(organizer, times(1)).onBackPressedOnTaskRoot(any()); } |