summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/Activity.java328
-rw-r--r--core/java/android/app/ActivityClient.java476
-rw-r--r--core/java/android/app/ActivityThread.java59
-rw-r--r--core/java/android/app/IActivityClientController.aidl108
-rw-r--r--core/java/android/app/IActivityTaskManager.aidl88
-rw-r--r--core/java/android/app/servertransaction/PauseActivityItem.java11
-rw-r--r--core/java/android/app/servertransaction/PendingTransactionActions.java12
-rw-r--r--core/java/android/app/servertransaction/ResumeActivityItem.java11
-rw-r--r--core/java/android/app/servertransaction/TopResumedActivityChangeItem.java9
-rw-r--r--core/java/android/view/Window.java3
-rw-r--r--core/java/com/android/internal/widget/DecorCaptionView.java9
-rw-r--r--core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java16
-rw-r--r--data/etc/services.core.protolog.json36
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java24
-rw-r--r--services/core/java/com/android/server/wm/ActivityClientController.java1046
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java2
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerService.java1074
-rw-r--r--services/core/java/com/android/server/wm/DragAndDropPermissionsHandler.java25
-rw-r--r--services/core/java/com/android/server/wm/DragState.java3
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java21
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java8
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java14
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());
}