Moved some activities implementation to ActivityTaskManagerService (2/n)
Second step in unifying the window hierarchy that is currently split
within AM and WM packages. We move some of the API implementation for
activities from ActivityManagerService.java to
ActivityTaskManagerService.java.
Test: Existing tests pass
Test: go/wm-smoke-auto
Bug: 80414790
Change-Id: I23dcd924493d8ad1e0b6e3a55386fd72b0146605
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index 1ccce17..6c359fe 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -26,9 +26,11 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
+import android.app.ActivityTaskManager;
import android.app.ActivityManagerInternal;
import android.app.AppGlobals;
import android.app.IActivityManager;
+import android.app.IActivityTaskManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ApplicationInfo;
@@ -1296,13 +1298,13 @@
}
}
- IActivityManager am = ActivityManager.getService();
+ final IActivityTaskManager atm = ActivityTaskManager.getService();
// Only remove sessions which's activities are not known to the activity manager anymore
for (int i = 0; i < numSessionsToRemove; i++) {
try {
// The activity manager cannot resolve activities that have been removed
- if (am.getActivityClassForToken(sessionsToRemove.valueAt(i)) != null) {
+ if (atm.getActivityClassForToken(sessionsToRemove.valueAt(i)) != null) {
sessionsToRemove.removeAt(i);
i--;
numSessionsToRemove--;
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 1168f55..767b2f7 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -38,6 +38,7 @@
import android.annotation.Nullable;
import android.app.Activity;
import android.app.ActivityManager;
+import android.app.ActivityTaskManager;
import android.app.IAssistDataReceiver;
import android.app.assist.AssistStructure;
import android.app.assist.AssistStructure.AutofillOverlay;
@@ -515,7 +516,7 @@
receiverExtras.putInt(EXTRA_REQUEST_ID, requestId);
final long identity = Binder.clearCallingIdentity();
try {
- if (!ActivityManager.getService().requestAutofillData(mAssistReceiver,
+ if (!ActivityTaskManager.getService().requestAutofillData(mAssistReceiver,
receiverExtras, mActivityToken, flags)) {
Slog.w(TAG, "failed to request autofill data for " + mActivityToken);
}
diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java
index 6b5366a..c29fc7f 100644
--- a/services/core/java/com/android/server/UiModeManagerService.java
+++ b/services/core/java/com/android/server/UiModeManagerService.java
@@ -19,6 +19,7 @@
import android.annotation.Nullable;
import android.app.Activity;
import android.app.ActivityManager;
+import android.app.ActivityTaskManager;
import android.app.IUiModeManager;
import android.app.Notification;
import android.app.NotificationManager;
@@ -475,7 +476,7 @@
mSetUiMode = mConfiguration.uiMode;
try {
- ActivityManager.getService().updateConfiguration(mConfiguration);
+ ActivityTaskManager.getService().updateConfiguration(mConfiguration);
} catch (RemoteException e) {
Slog.w(TAG, "Failure communicating with activity manager", e);
}
@@ -637,7 +638,7 @@
Intent homeIntent = buildHomeIntent(category);
if (Sandman.shouldStartDockApp(getContext(), homeIntent)) {
try {
- int result = ActivityManager.getService().startActivityWithConfig(
+ int result = ActivityTaskManager.getService().startActivityWithConfig(
null, null, homeIntent, null, null, null, 0, 0,
mConfiguration, null, UserHandle.USER_CURRENT);
if (ActivityManager.isStartResultSuccessful(result)) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 215670b..97c3fe4 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -601,17 +601,6 @@
// Must be kept in sync with Am.
private static final int INSTRUMENTATION_FLAG_DISABLE_HIDDEN_API_CHECKS = 1 << 0;
- // How long to wait in getAssistContextExtras for the activity and foreground services
- // to respond with the result.
- static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
-
- // How long top wait when going through the modern assist (which doesn't need to block
- // on getting this result before starting to launch its UI).
- static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
-
- // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
- static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
-
// Maximum number of persisted Uri grants a package is allowed
static final int MAX_PERSISTED_URI_GRANTS = 128;
@@ -679,9 +668,6 @@
/** All system services */
SystemServiceManager mSystemServiceManager;
- // Wrapper around VoiceInteractionServiceManager
- private AssistUtils mAssistUtils;
-
// Keeps track of the active voice interaction service component, notified from
// VoiceInteractionManagerService
ComponentName mActiveVoiceInteractionServiceComponent;
@@ -690,7 +676,7 @@
/** Run all ActivityStacks through this */
final ActivityStackSupervisor mStackSupervisor;
- private final KeyguardController mKeyguardController;
+ final KeyguardController mKeyguardController;
private final ActivityStartController mActivityStartController;
@@ -741,7 +727,7 @@
* of the time but could be different when we're pausing one activity before we resume
* another activity.
*/
- private ActivityRecord mLastResumedActivity;
+ ActivityRecord mLastResumedActivity;
/**
* The activity that is currently being traced as the active resumed activity.
@@ -844,45 +830,6 @@
sThreadPriorityBooster.reset();
}
- public class PendingAssistExtras extends Binder implements Runnable {
- public final ActivityRecord activity;
- public boolean isHome;
- public final Bundle extras;
- public final Intent intent;
- public final String hint;
- public final IAssistDataReceiver receiver;
- public final int userHandle;
- public boolean haveResult = false;
- public Bundle result = null;
- public AssistStructure structure = null;
- public AssistContent content = null;
- public Bundle receiverExtras;
-
- public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
- String _hint, IAssistDataReceiver _receiver, Bundle _receiverExtras,
- int _userHandle) {
- activity = _activity;
- extras = _extras;
- intent = _intent;
- hint = _hint;
- receiver = _receiver;
- receiverExtras = _receiverExtras;
- userHandle = _userHandle;
- }
-
- @Override
- public void run() {
- Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
- synchronized (this) {
- haveResult = true;
- notifyAll();
- }
- pendingAssistExtrasTimedOut(this);
- }
- }
-
- final ArrayList<PendingAssistExtras> mPendingAssistExtras = new ArrayList<>();
-
/**
* Process management.
*/
@@ -1427,22 +1374,6 @@
*/
private Configuration mTempConfig = new Configuration();
- private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
- new UpdateConfigurationResult();
- private static final class UpdateConfigurationResult {
- // Configuration changes that were updated.
- int changes;
- // If the activity was relaunched to match the new configuration.
- boolean activityRelaunched;
-
- void reset() {
- changes = 0;
- activityRelaunched = false;
- }
- }
-
- boolean mSuppressResizeConfigChanges;
-
/**
* Hardware-reported OpenGLES version.
*/
@@ -1548,11 +1479,6 @@
private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
/**
- * State of external calls telling us if the device is awake or asleep.
- */
- private boolean mKeyguardShown = false;
-
- /**
* Set if we are shutting down the system, similar to sleeping.
*/
boolean mShuttingDown = false;
@@ -1974,10 +1900,6 @@
PackageManagerInternal mPackageManagerInt;
- // VoiceInteraction session ID that changes for each new request except when
- // being called for multiwindow assist in a single session.
- private int mViSessionId = 1000;
-
final boolean mPermissionReviewRequired;
boolean mHasHeavyWeightFeature;
@@ -3555,7 +3477,7 @@
// move to something different. Just finish the session, we can't
// return to it and retain the proper state and synchronization with
// the voice interaction service.
- finishVoiceTask(session);
+ mActivityTaskManager.finishVoiceTask(session);
}
}
}
@@ -3595,74 +3517,21 @@
@Override
public void setFocusedStack(int stackId) {
- enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
- if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
- final long callingId = Binder.clearCallingIdentity();
- try {
- synchronized (this) {
- final ActivityStack stack = mStackSupervisor.getStack(stackId);
- if (stack == null) {
- Slog.w(TAG, "setFocusedStack: No stack with id=" + stackId);
- return;
- }
- final ActivityRecord r = stack.topRunningActivityLocked();
- if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
- }
- }
- } finally {
- Binder.restoreCallingIdentity(callingId);
- }
- }
-
- @Override
- public void setFocusedTask(int taskId) {
- enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
- if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
- final long callingId = Binder.clearCallingIdentity();
- try {
- synchronized (this) {
- final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
- if (task == null) {
- return;
- }
- final ActivityRecord r = task.topRunningActivityLocked();
- if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
- }
- }
- } finally {
- Binder.restoreCallingIdentity(callingId);
- }
+ mActivityTaskManager.setFocusedStack(stackId);
}
/** Sets the task stack listener that gets callbacks when a task stack changes. */
@Override
- public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
- enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
- "registerTaskStackListener()");
- mTaskChangeNotificationController.registerTaskStackListener(listener);
+ public void registerTaskStackListener(ITaskStackListener listener) {
+ mActivityTaskManager.registerTaskStackListener(listener);
}
/**
* Unregister a task stack listener so that it stops receiving callbacks.
*/
@Override
- public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
- enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
- "unregisterTaskStackListener()");
- mTaskChangeNotificationController.unregisterTaskStackListener(listener);
- }
-
- @Override
- public void notifyActivityDrawn(IBinder token) {
- if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
- synchronized (this) {
- ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
- if (r != null) {
- r.getStack().notifyActivityDrawnLocked(r);
- }
- }
+ public void unregisterTaskStackListener(ITaskStackListener listener) {
+ mActivityTaskManager.unregisterTaskStackListener(listener);
}
final void applyUpdateLockStateLocked(ActivityRecord r) {
@@ -4733,23 +4602,6 @@
}
@Override
- public int getFrontActivityScreenCompatMode() {
- enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
- synchronized (this) {
- return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
- }
- }
-
- @Override
- public void setFrontActivityScreenCompatMode(int mode) {
- enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
- "setFrontActivityScreenCompatMode");
- synchronized (this) {
- mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
- }
- }
-
- @Override
public int getPackageScreenCompatMode(String packageName) {
enforceNotIsolatedCaller("getPackageScreenCompatMode");
synchronized (this) {
@@ -5086,329 +4938,37 @@
}
@Override
- public final int startActivity(IApplicationThread caller, String callingPackage,
+ public int startActivity(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
- return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
- resultWho, requestCode, startFlags, profilerInfo, bOptions,
- UserHandle.getCallingUserId());
+ return mActivityTaskManager.startActivity(caller, callingPackage, intent, resolvedType,
+ resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions);
}
@Override
public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
- return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
- resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
- true /*validateIncomingUser*/);
- }
-
- public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
- Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
- int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
- boolean validateIncomingUser) {
- enforceNotIsolatedCaller("startActivity");
-
- userId = mActivityStartController.checkTargetUser(userId, validateIncomingUser,
- Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
-
- // TODO: Switch to user app stacks here.
- return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
- .setCaller(caller)
- .setCallingPackage(callingPackage)
- .setResolvedType(resolvedType)
- .setResultTo(resultTo)
- .setResultWho(resultWho)
- .setRequestCode(requestCode)
- .setStartFlags(startFlags)
- .setProfilerInfo(profilerInfo)
- .setActivityOptions(bOptions)
- .setMayWait(userId)
- .execute();
-
+ return mActivityTaskManager.startActivityAsUser(caller, callingPackage, intent,
+ resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions,
+ userId);
}
@Override
- public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
- Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
- int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
- int userId) {
-
- // This is very dangerous -- it allows you to perform a start activity (including
- // permission grants) as any app that may launch one of your own activities. So
- // we will only allow this to be done from activities that are part of the core framework,
- // and then only when they are running as the system.
- final ActivityRecord sourceRecord;
- final int targetUid;
- final String targetPackage;
- final boolean isResolver;
- synchronized (this) {
- if (resultTo == null) {
- throw new SecurityException("Must be called from an activity");
- }
- sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
- if (sourceRecord == null) {
- throw new SecurityException("Called with bad activity token: " + resultTo);
- }
- if (!sourceRecord.info.packageName.equals("android")) {
- throw new SecurityException(
- "Must be called from an activity that is declared in the android package");
- }
- if (sourceRecord.app == null) {
- throw new SecurityException("Called without a process attached to activity");
- }
- if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) {
- // This is still okay, as long as this activity is running under the
- // uid of the original calling activity.
- if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
- throw new SecurityException(
- "Calling activity in uid " + sourceRecord.app.uid
- + " must be system uid or original calling uid "
- + sourceRecord.launchedFromUid);
- }
- }
- if (ignoreTargetSecurity) {
- if (intent.getComponent() == null) {
- throw new SecurityException(
- "Component must be specified with ignoreTargetSecurity");
- }
- if (intent.getSelector() != null) {
- throw new SecurityException(
- "Selector not allowed with ignoreTargetSecurity");
- }
- }
- targetUid = sourceRecord.launchedFromUid;
- targetPackage = sourceRecord.launchedFromPackage;
- isResolver = sourceRecord.isResolverOrChildActivity();
- }
-
- if (userId == UserHandle.USER_NULL) {
- userId = UserHandle.getUserId(sourceRecord.app.uid);
- }
-
- // TODO: Switch to user app stacks here.
- try {
- return mActivityStartController.obtainStarter(intent, "startActivityAsCaller")
- .setCallingUid(targetUid)
- .setCallingPackage(targetPackage)
- .setResolvedType(resolvedType)
- .setResultTo(resultTo)
- .setResultWho(resultWho)
- .setRequestCode(requestCode)
- .setStartFlags(startFlags)
- .setActivityOptions(bOptions)
- .setMayWait(userId)
- .setIgnoreTargetSecurity(ignoreTargetSecurity)
- .setFilterCallingUid(isResolver ? 0 /* system */ : targetUid)
- .execute();
- } catch (SecurityException e) {
- // XXX need to figure out how to propagate to original app.
- // A SecurityException here is generally actually a fault of the original
- // calling activity (such as a fairly granting permissions), so propagate it
- // back to them.
- /*
- StringBuilder msg = new StringBuilder();
- msg.append("While launching");
- msg.append(intent.toString());
- msg.append(": ");
- msg.append(e.getMessage());
- */
- throw e;
- }
- }
-
- @Override
- public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
- Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
- int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
- enforceNotIsolatedCaller("startActivityAndWait");
- userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
- userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
- WaitResult res = new WaitResult();
- // TODO: Switch to user app stacks here.
- mActivityStartController.obtainStarter(intent, "startActivityAndWait")
- .setCaller(caller)
- .setCallingPackage(callingPackage)
- .setResolvedType(resolvedType)
- .setResultTo(resultTo)
- .setResultWho(resultWho)
- .setRequestCode(requestCode)
- .setStartFlags(startFlags)
- .setActivityOptions(bOptions)
- .setMayWait(userId)
- .setProfilerInfo(profilerInfo)
- .setWaitResult(res)
- .execute();
- return res;
- }
-
- @Override
- public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
- Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
- int startFlags, Configuration config, Bundle bOptions, int userId) {
- enforceNotIsolatedCaller("startActivityWithConfig");
- userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
- userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
- // TODO: Switch to user app stacks here.
- return mActivityStartController.obtainStarter(intent, "startActivityWithConfig")
- .setCaller(caller)
- .setCallingPackage(callingPackage)
- .setResolvedType(resolvedType)
- .setResultTo(resultTo)
- .setResultWho(resultWho)
- .setRequestCode(requestCode)
- .setStartFlags(startFlags)
- .setGlobalConfiguration(config)
- .setActivityOptions(bOptions)
- .setMayWait(userId)
- .execute();
- }
-
- @Override
- public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
- IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
- String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
- throws TransactionTooLargeException {
- enforceNotIsolatedCaller("startActivityIntentSender");
- // Refuse possible leaked file descriptors
- if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
- throw new IllegalArgumentException("File descriptors passed in Intent");
- }
-
- if (!(target instanceof PendingIntentRecord)) {
- throw new IllegalArgumentException("Bad PendingIntent object");
- }
-
- PendingIntentRecord pir = (PendingIntentRecord)target;
-
- synchronized (this) {
- // If this is coming from the currently resumed activity, it is
- // effectively saying that app switches are allowed at this point.
- final ActivityStack stack = getFocusedStack();
- if (stack.mResumedActivity != null &&
- stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
- mAppSwitchesAllowedTime = 0;
- }
- }
- int ret = pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
- resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
- return ret;
- }
-
- @Override
- public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
- Intent intent, String resolvedType, IVoiceInteractionSession session,
- IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
- Bundle bOptions, int userId) {
- enforceCallingPermission(BIND_VOICE_INTERACTION, "startVoiceActivity()");
- if (session == null || interactor == null) {
- throw new NullPointerException("null session or interactor");
- }
- userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
- ALLOW_FULL_ONLY, "startVoiceActivity", null);
- // TODO: Switch to user app stacks here.
- return mActivityStartController.obtainStarter(intent, "startVoiceActivity")
- .setCallingUid(callingUid)
- .setCallingPackage(callingPackage)
- .setResolvedType(resolvedType)
- .setVoiceSession(session)
- .setVoiceInteractor(interactor)
- .setStartFlags(startFlags)
- .setProfilerInfo(profilerInfo)
- .setActivityOptions(bOptions)
- .setMayWait(userId)
- .execute();
- }
-
- @Override
- public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
- Intent intent, String resolvedType, Bundle bOptions, int userId) {
- enforceCallingPermission(BIND_VOICE_INTERACTION, "startAssistantActivity()");
- userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
- ALLOW_FULL_ONLY, "startAssistantActivity", null);
-
- return mActivityStartController.obtainStarter(intent, "startAssistantActivity")
- .setCallingUid(callingUid)
- .setCallingPackage(callingPackage)
- .setResolvedType(resolvedType)
- .setActivityOptions(bOptions)
- .setMayWait(userId)
- .execute();
+ public final int startActivityFromRecents(int taskId, Bundle bOptions) {
+ return mActivityTaskManager.startActivityFromRecents(taskId, bOptions);
}
@Override
public void startRecentsActivity(Intent intent, IAssistDataReceiver assistDataReceiver,
- IRecentsAnimationRunner recentsAnimationRunner) {
- enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "startRecentsActivity()");
- final int callingPid = Binder.getCallingPid();
- final long origId = Binder.clearCallingIdentity();
- try {
- synchronized (this) {
- final ComponentName recentsComponent = mRecentTasks.getRecentsComponent();
- final int recentsUid = mRecentTasks.getRecentsComponentUid();
-
- // Start a new recents animation
- final RecentsAnimation anim = new RecentsAnimation(this, mStackSupervisor,
- mActivityStartController, mWindowManager, mUserController, callingPid);
- anim.startRecentsActivity(intent, recentsAnimationRunner, recentsComponent,
- recentsUid, assistDataReceiver);
- }
- } finally {
- Binder.restoreCallingIdentity(origId);
- }
+ IRecentsAnimationRunner recentsAnimationRunner) {
+ mActivityTaskManager.startRecentsActivity(
+ intent, assistDataReceiver, recentsAnimationRunner);
}
@Override
public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
- enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()");
- final long callingUid = Binder.getCallingUid();
- final long origId = Binder.clearCallingIdentity();
- try {
- synchronized (this) {
- // Cancel the recents animation synchronously (do not hold the WM lock)
- mWindowManager.cancelRecentsAnimationSynchronously(restoreHomeStackPosition
- ? REORDER_MOVE_TO_ORIGINAL_POSITION
- : REORDER_KEEP_IN_PLACE, "cancelRecentsAnimation/uid=" + callingUid);
- }
- } finally {
- Binder.restoreCallingIdentity(origId);
- }
- }
-
- @Override
- public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
- throws RemoteException {
- Slog.i(TAG, "Activity tried to startVoiceInteraction");
- synchronized (this) {
- ActivityRecord activity = getFocusedStack().getTopActivity();
- 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) throws RemoteException {
- LocalServices.getService(VoiceInteractionManagerInternal.class)
- .stopLocalVoiceInteraction(callingActivity);
- }
-
- @Override
- public boolean supportsLocalVoiceInteraction() throws RemoteException {
- return LocalServices.getService(VoiceInteractionManagerInternal.class)
- .supportsLocalVoiceInteraction();
+ mActivityTaskManager.cancelRecentsAnimation(restoreHomeStackPosition);
}
@GuardedBy("this")
@@ -5449,197 +5009,6 @@
}
}
- @Override
- public boolean startNextMatchingActivity(IBinder callingActivity,
- Intent intent, Bundle bOptions) {
- // Refuse possible leaked file descriptors
- if (intent != null && intent.hasFileDescriptors() == true) {
- throw new IllegalArgumentException("File descriptors passed in Intent");
- }
- SafeActivityOptions options = SafeActivityOptions.fromBundle(bOptions);
-
- synchronized (this) {
- final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
- if (r == null) {
- SafeActivityOptions.abort(options);
- return false;
- }
- if (r.app == null || r.app.thread == null) {
- // The caller is not running... d'oh!
- SafeActivityOptions.abort(options);
- return false;
- }
- intent = new Intent(intent);
- // The caller is not allowed to change the data.
- intent.setDataAndType(r.intent.getData(), r.intent.getType());
- // And we are resetting to find the next component...
- intent.setComponent(null);
-
- final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
-
- ActivityInfo aInfo = null;
- try {
- List<ResolveInfo> resolves =
- AppGlobals.getPackageManager().queryIntentActivities(
- intent, r.resolvedType,
- PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
- UserHandle.getCallingUserId()).getList();
-
- // Look for the original activity in the list...
- final int N = resolves != null ? resolves.size() : 0;
- for (int i=0; i<N; i++) {
- ResolveInfo rInfo = resolves.get(i);
- if (rInfo.activityInfo.packageName.equals(r.packageName)
- && rInfo.activityInfo.name.equals(r.info.name)) {
- // We found the current one... the next matching is
- // after it.
- i++;
- if (i<N) {
- aInfo = resolves.get(i).activityInfo;
- }
- if (debug) {
- Slog.v(TAG, "Next matching activity: found current " + r.packageName
- + "/" + r.info.name);
- Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
- ? "null" : aInfo.packageName + "/" + aInfo.name));
- }
- break;
- }
- }
- } catch (RemoteException e) {
- }
-
- if (aInfo == null) {
- // Nobody who is next!
- SafeActivityOptions.abort(options);
- if (debug) Slog.d(TAG, "Next matching activity: nothing found");
- return false;
- }
-
- intent.setComponent(new ComponentName(
- aInfo.applicationInfo.packageName, aInfo.name));
- intent.setFlags(intent.getFlags()&~(
- Intent.FLAG_ACTIVITY_FORWARD_RESULT|
- Intent.FLAG_ACTIVITY_CLEAR_TOP|
- Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
- FLAG_ACTIVITY_NEW_TASK));
-
- // Okay now we need to start the new activity, replacing the
- // currently running activity. This is a little tricky because
- // we want to start the new one as if the current one is finished,
- // but not finish the current one first so that there is no flicker.
- // And thus...
- final boolean wasFinishing = r.finishing;
- r.finishing = true;
-
- // Propagate reply information over to the new activity.
- final ActivityRecord resultTo = r.resultTo;
- final String resultWho = r.resultWho;
- final int requestCode = r.requestCode;
- r.resultTo = null;
- if (resultTo != null) {
- resultTo.removeResultsLocked(r, resultWho, requestCode);
- }
-
- final long origId = Binder.clearCallingIdentity();
- // TODO(b/64750076): Check if calling pid should really be -1.
- final int res = mActivityStartController
- .obtainStarter(intent, "startNextMatchingActivity")
- .setCaller(r.app.thread)
- .setResolvedType(r.resolvedType)
- .setActivityInfo(aInfo)
- .setResultTo(resultTo != null ? resultTo.appToken : null)
- .setResultWho(resultWho)
- .setRequestCode(requestCode)
- .setCallingPid(-1)
- .setCallingUid(r.launchedFromUid)
- .setCallingPackage(r.launchedFromPackage)
- .setRealCallingPid(-1)
- .setRealCallingUid(r.launchedFromUid)
- .setActivityOptions(options)
- .execute();
- Binder.restoreCallingIdentity(origId);
-
- r.finishing = wasFinishing;
- if (res != ActivityManager.START_SUCCESS) {
- return false;
- }
- return true;
- }
- }
-
- @Override
- public final int startActivityFromRecents(int taskId, Bundle bOptions) {
- enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS,
- "startActivityFromRecents()");
-
- final int callingPid = Binder.getCallingPid();
- final int callingUid = Binder.getCallingUid();
- final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(bOptions);
- final long origId = Binder.clearCallingIdentity();
- try {
- synchronized (this) {
- return mStackSupervisor.startActivityFromRecents(callingPid, callingUid, taskId,
- safeOptions);
- }
- } finally {
- Binder.restoreCallingIdentity(origId);
- }
- }
-
- @Override
- public final int startActivities(IApplicationThread caller, String callingPackage,
- Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
- int userId) {
- final String reason = "startActivities";
- enforceNotIsolatedCaller(reason);
- userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
- userId, false, ALLOW_FULL_ONLY, reason, null);
- // TODO: Switch to user app stacks here.
- int ret = mActivityStartController.startActivities(caller, -1, callingPackage,
- intents, resolvedTypes, resultTo, SafeActivityOptions.fromBundle(bOptions), userId,
- reason);
- return ret;
- }
-
- @Override
- public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
- synchronized (this) {
- ActivityRecord r = ActivityRecord.isInStackLocked(token);
- if (r == null) {
- return;
- }
- r.reportFullyDrawnLocked(restoredFromBundle);
- }
- }
-
- @Override
- public void setRequestedOrientation(IBinder token, int requestedOrientation) {
- synchronized (this) {
- 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 (this) {
- ActivityRecord r = ActivityRecord.isInStackLocked(token);
- if (r == null) {
- return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
- }
- return r.getRequestedOrientation();
- }
- }
-
/**
* This is the internal entry point for handling Activity.finish().
*
@@ -5653,76 +5022,12 @@
@Override
public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
int finishTask) {
- // Refuse possible leaked file descriptors
- if (resultData != null && resultData.hasFileDescriptors() == true) {
- throw new IllegalArgumentException("File descriptors passed in Intent");
- }
+ return mActivityTaskManager.finishActivity(token, resultCode, resultData, finishTask);
+ }
- synchronized(this) {
- ActivityRecord r = ActivityRecord.isInStackLocked(token);
- if (r == null) {
- return true;
- }
- // Keep track of the root activity of the task before we finish it
- TaskRecord tr = r.getTask();
- 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 (mLockTaskController.activityBlockedFromFinish(r)) {
- return false;
- }
-
- if (mController != null) {
- // Find the first activity that is not finishing.
- ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
- 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;
- }
- }
- }
- final long origId = Binder.clearCallingIdentity();
- 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.
- res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
- finishWithRootActivity, "finish-activity");
- if (!res) {
- Slog.i(TAG, "Removing task failed to finish activity");
- }
- } else {
- res = tr.getStack().requestFinishActivityLocked(token, resultCode,
- resultData, "app-request", true);
- if (!res) {
- Slog.i(TAG, "Failed to finish by app-request");
- }
- }
- return res;
- } finally {
- Binder.restoreCallingIdentity(origId);
- }
- }
+ @Override
+ public void setRequestedOrientation(IBinder token, int requestedOrientation) {
+ mActivityTaskManager.setRequestedOrientation(token, requestedOrientation);
}
@Override
@@ -5776,117 +5081,6 @@
}
}
- @Override
- public final void finishSubActivity(IBinder token, String resultWho,
- int requestCode) {
- synchronized(this) {
- final long origId = Binder.clearCallingIdentity();
- ActivityRecord r = ActivityRecord.isInStackLocked(token);
- if (r != null) {
- r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
- }
- Binder.restoreCallingIdentity(origId);
- }
- }
-
- @Override
- public boolean finishActivityAffinity(IBinder token) {
- synchronized(this) {
- 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.
- final TaskRecord task = r.getTask();
- if (mLockTaskController.activityBlockedFromFinish(r)) {
- return false;
- }
- return task.getStack().finishActivityAffinityLocked(r);
- } finally {
- Binder.restoreCallingIdentity(origId);
- }
- }
- }
-
- @Override
- public void finishVoiceTask(IVoiceInteractionSession session) {
- synchronized (this) {
- final long origId = Binder.clearCallingIdentity();
- try {
- // TODO: VI Consider treating local voice interactions and voice tasks
- // differently here
- mStackSupervisor.finishVoiceTask(session);
- } finally {
- Binder.restoreCallingIdentity(origId);
- }
- }
-
- }
-
- @Override
- public boolean releaseActivityInstance(IBinder token) {
- synchronized(this) {
- final long origId = Binder.clearCallingIdentity();
- try {
- ActivityRecord r = ActivityRecord.isInStackLocked(token);
- if (r == null) {
- return false;
- }
- return r.getStack().safelyDestroyActivityLocked(r, "app-req");
- } finally {
- Binder.restoreCallingIdentity(origId);
- }
- }
- }
-
- @Override
- public void releaseSomeActivities(IApplicationThread appInt) {
- synchronized(this) {
- final long origId = Binder.clearCallingIdentity();
- try {
- ProcessRecord app = getRecordForAppLocked(appInt);
- mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
- } finally {
- Binder.restoreCallingIdentity(origId);
- }
- }
- }
-
- @Override
- public boolean willActivityBeVisible(IBinder token) {
- synchronized(this) {
- ActivityStack stack = ActivityRecord.getStackLocked(token);
- if (stack != null) {
- return stack.willActivityBeVisibleLocked(token);
- }
- return false;
- }
- }
-
- @Override
- public void overridePendingTransition(IBinder token, String packageName,
- int enterAnim, int exitAnim) {
- synchronized(this) {
- ActivityRecord self = ActivityRecord.isInStackLocked(token);
- if (self == null) {
- return;
- }
-
- final long origId = Binder.clearCallingIdentity();
-
- if (self.isState(ActivityState.RESUMED, ActivityState.PAUSING)) {
- mWindowManager.overridePendingAppTransition(packageName,
- enterAnim, exitAnim, null);
- }
-
- Binder.restoreCallingIdentity(origId);
- }
- }
-
/**
* Main function for removing an existing process from the activity manager
* as a result of that process going away. Clears out all connections
@@ -7813,25 +7007,6 @@
}
}
- @Override
- public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
- final long origId = Binder.clearCallingIdentity();
- synchronized (this) {
- ActivityStack stack = ActivityRecord.getStackLocked(token);
- if (stack != null) {
- ActivityRecord r =
- mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
- false /* processPausingActivities */, config);
- if (stopProfiling) {
- if ((mProfileProc == r.app) && mProfilerInfo != null) {
- clearProfilerLocked();
- }
- }
- }
- }
- Binder.restoreCallingIdentity(origId);
- }
-
void postFinishBooting(boolean finishBooting, boolean enableScreen) {
mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
finishBooting ? 1 : 0, enableScreen ? 1 : 0));
@@ -7855,19 +7030,6 @@
mWindowManager.showBootMessage(msg, always);
}
- @Override
- public void keyguardGoingAway(int flags) {
- enforceNotIsolatedCaller("keyguardGoingAway");
- final long token = Binder.clearCallingIdentity();
- try {
- synchronized (this) {
- mKeyguardController.keyguardGoingAway(flags);
- }
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
/**
* @return whther the keyguard is currently locked.
*/
@@ -8019,155 +7181,6 @@
}
@Override
- public final void activityResumed(IBinder token) {
- final long origId = Binder.clearCallingIdentity();
- synchronized(this) {
- ActivityRecord.activityResumedLocked(token);
- mWindowManager.notifyAppResumedFinished(token);
- }
- Binder.restoreCallingIdentity(origId);
- }
-
- @Override
- public final void activityPaused(IBinder token) {
- final long origId = Binder.clearCallingIdentity();
- synchronized(this) {
- ActivityStack stack = ActivityRecord.getStackLocked(token);
- if (stack != null) {
- stack.activityPausedLocked(token, false);
- }
- }
- 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();
-
- synchronized (this) {
- final ActivityRecord r = ActivityRecord.isInStackLocked(token);
- if (r != null) {
- r.activityStoppedLocked(icicle, persistentState, description);
- }
- }
-
- trimApplications();
-
- Binder.restoreCallingIdentity(origId);
- }
-
- @Override
- public final void activityDestroyed(IBinder token) {
- if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
- synchronized (this) {
- ActivityStack stack = ActivityRecord.getStackLocked(token);
- if (stack != null) {
- stack.activityDestroyedLocked(token, "activityDestroyed");
- }
- }
- }
-
- @Override
- public final void activityRelaunched(IBinder token) {
- final long origId = Binder.clearCallingIdentity();
- synchronized (this) {
- mStackSupervisor.activityRelaunchedLocked(token);
- }
- Binder.restoreCallingIdentity(origId);
- }
-
- @Override
- public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
- int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
- if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
- + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
- synchronized (this) {
- ActivityRecord record = ActivityRecord.isInStackLocked(token);
- if (record == null) {
- throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
- + "found for: " + token);
- }
- record.setSizeConfigurations(horizontalSizeConfiguration,
- verticalSizeConfigurations, smallestSizeConfigurations);
- }
- }
-
- @Override
- public final void notifyLaunchTaskBehindComplete(IBinder token) {
- mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
- }
-
- @Override
- public final void notifyEnterAnimationComplete(IBinder token) {
- mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
- }
-
- @Override
- public String getCallingPackage(IBinder token) {
- synchronized (this) {
- ActivityRecord r = getCallingRecordLocked(token);
- return r != null ? r.info.packageName : null;
- }
- }
-
- @Override
- public ComponentName getCallingActivity(IBinder token) {
- synchronized (this) {
- 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;
- }
-
- @Override
- public ComponentName getActivityClassForToken(IBinder token) {
- synchronized(this) {
- ActivityRecord r = ActivityRecord.isInStackLocked(token);
- if (r == null) {
- return null;
- }
- return r.intent.getComponent();
- }
- }
-
- @Override
- public String getPackageForToken(IBinder token) {
- synchronized(this) {
- ActivityRecord r = ActivityRecord.isInStackLocked(token);
- if (r == null) {
- return null;
- }
- return r.packageName;
- }
- }
-
- @Override
- public boolean isRootVoiceInteraction(IBinder token) {
- synchronized(this) {
- ActivityRecord r = ActivityRecord.isInStackLocked(token);
- if (r == null) {
- return false;
- }
- return r.rootVoiceInteraction;
- }
- }
-
- @Override
public IIntentSender getIntentSender(int type,
String packageName, IBinder token, String resultWho,
int requestCode, Intent[] intents, String[] resolvedTypes,
@@ -8659,199 +7672,6 @@
return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
}
- @Override
- public boolean isInMultiWindowMode(IBinder token) {
- final long origId = Binder.clearCallingIdentity();
- try {
- synchronized(this) {
- final ActivityRecord r = ActivityRecord.isInStackLocked(token);
- if (r == null) {
- return false;
- }
- // An activity is consider to be in multi-window mode if its task isn't fullscreen.
- return r.inMultiWindowMode();
- }
- } finally {
- Binder.restoreCallingIdentity(origId);
- }
- }
-
- @Override
- public boolean isInPictureInPictureMode(IBinder token) {
- final long origId = Binder.clearCallingIdentity();
- try {
- synchronized(this) {
- return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
- }
- } finally {
- Binder.restoreCallingIdentity(origId);
- }
- }
-
- private boolean isInPictureInPictureMode(ActivityRecord r) {
- if (r == null || r.getStack() == null || !r.inPinnedWindowingMode()
- || r.getStack().isInStackLocked(r) == null) {
- return false;
- }
-
- // If we are animating to fullscreen then we have already dispatched the PIP mode
- // changed, so we should reflect that check here as well.
- final PinnedActivityStack stack = r.getStack();
- final PinnedStackWindowController windowController = stack.getWindowContainerController();
- return !windowController.isAnimatingBoundsToFullscreen();
- }
-
- @Override
- public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
- final long origId = Binder.clearCallingIdentity();
- try {
- synchronized(this) {
- final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
- "enterPictureInPictureMode", token, params);
-
- // If the activity is already in picture in picture mode, then just return early
- if (isInPictureInPictureMode(r)) {
- return true;
- }
-
- // Activity supports picture-in-picture, now check that we can enter PiP at this
- // point, if it is
- if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
- false /* beforeStopping */)) {
- return false;
- }
-
- final Runnable enterPipRunnable = () -> {
- // Only update the saved args from the args that are set
- r.pictureInPictureArgs.copyOnlySet(params);
- final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
- final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
- // Adjust the source bounds by the insets for the transition down
- final Rect sourceBounds = new Rect(r.pictureInPictureArgs.getSourceRectHint());
- mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio,
- "enterPictureInPictureMode");
- final PinnedActivityStack stack = r.getStack();
- stack.setPictureInPictureAspectRatio(aspectRatio);
- stack.setPictureInPictureActions(actions);
- MetricsLoggerWrapper.logPictureInPictureEnter(mContext, r.appInfo.uid,
- r.shortComponentName, r.supportsEnterPipOnTaskSwitch);
- logPictureInPictureArgs(params);
- };
-
- if (isKeyguardLocked()) {
- // If the keyguard is showing or occluded, then try and dismiss it before
- // entering picture-in-picture (this will prompt the user to authenticate if the
- // device is currently locked).
- try {
- dismissKeyguard(token, new KeyguardDismissCallback() {
- @Override
- public void onDismissSucceeded() throws RemoteException {
- mHandler.post(enterPipRunnable);
- }
- }, null /* message */);
- } catch (RemoteException e) {
- // Local call
- }
- } else {
- // Enter picture in picture immediately otherwise
- enterPipRunnable.run();
- }
- return true;
- }
- } finally {
- Binder.restoreCallingIdentity(origId);
- }
- }
-
- @Override
- public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
- final long origId = Binder.clearCallingIdentity();
- try {
- synchronized(this) {
- final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
- "setPictureInPictureParams", token, params);
-
- // Only update the saved args from the args that are set
- r.pictureInPictureArgs.copyOnlySet(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 PinnedActivityStack stack = r.getStack();
- if (!stack.isAnimatingBoundsToFullscreen()) {
- stack.setPictureInPictureAspectRatio(
- r.pictureInPictureArgs.getAspectRatio());
- stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
- }
- }
- logPictureInPictureArgs(params);
- }
- } finally {
- Binder.restoreCallingIdentity(origId);
- }
- }
-
- @Override
- public int getMaxNumPictureInPictureActions(IBinder token) {
- // Currently, this is a static constant, but later, we may change this to be dependent on
- // the context of the activity
- return 3;
- }
-
- private void logPictureInPictureArgs(PictureInPictureParams params) {
- if (params.hasSetActions()) {
- MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
- params.getActions().size());
- }
- if (params.hasSetAspectRatio()) {
- LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
- lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
- MetricsLogger.action(lm);
- }
- }
-
- /**
- * 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.getStack().mDisplayId,
- 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(getMaxNumPictureInPictureActions(token));
-
- return r;
- }
-
// =========================================================
// PROCESS INFO
// =========================================================
@@ -10066,18 +8886,6 @@
}
}
- @Override
- public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
- enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
- synchronized(this) {
- ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
- if (r == null) {
- throw new IllegalArgumentException("Activity does not exist; token="
- + activityToken);
- }
- return r.getUriPermissionsLocked().getExternalTokenLocked();
- }
- }
/**
* @param uri This uri must NOT contain an embedded userId.
* @param sourceUserId The userId in which the uri is to be resolved.
@@ -10527,21 +9335,8 @@
// =========================================================
@Override
- public List<IBinder> getAppTasks(String callingPackage) {
- int callingUid = Binder.getCallingUid();
- long ident = Binder.clearCallingIdentity();
- try {
- synchronized(this) {
- return mRecentTasks.getAppTasksList(callingUid, callingPackage);
- }
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
-
- @Override
public List<RunningTaskInfo> getTasks(int maxNum) {
- return mActivityTaskManager.getTasks(maxNum);
+ return mActivityTaskManager.getTasks(maxNum);
}
@Override
@@ -10551,6 +9346,11 @@
maxNum, ignoreActivityType, ignoreWindowingMode);
}
+ @Override
+ public void cancelTaskWindowTransition(int taskId) {
+ mActivityTaskManager.cancelTaskWindowTransition(taskId);
+ }
+
boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
if (mRecentTasks.isCallerRecents(callingUid)) {
// Always allow the recents component to get tasks
@@ -10584,394 +9384,38 @@
}
@Override
- public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
- int userId) {
- final int callingUid = Binder.getCallingUid();
- userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
- false, ALLOW_FULL_ONLY, "getRecentTasks", null);
- final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
- callingUid);
- final boolean detailed = checkCallingPermission(
- android.Manifest.permission.GET_DETAILED_TASKS)
- == PackageManager.PERMISSION_GRANTED;
-
- synchronized (this) {
- return mRecentTasks.getRecentTasks(maxNum, flags, allowed, detailed, userId,
- callingUid);
- }
- }
-
- @Override
- public ActivityManager.TaskDescription getTaskDescription(int id) {
- synchronized (this) {
- enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getTaskDescription()");
- final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
- MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
- if (tr != null) {
- return tr.lastTaskDescription;
- }
- }
- return null;
- }
-
- @Override
- public int addAppTask(IBinder activityToken, Intent intent,
- ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
- final int callingUid = Binder.getCallingUid();
- final long callingIdent = Binder.clearCallingIdentity();
-
- try {
- synchronized (this) {
- ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
- if (r == null) {
- throw new IllegalArgumentException("Activity does not exist; token="
- + activityToken);
- }
- ComponentName comp = intent.getComponent();
- if (comp == null) {
- throw new IllegalArgumentException("Intent " + intent
- + " must specify explicit component");
- }
- if (thumbnail.getWidth() != mThumbnailWidth
- || thumbnail.getHeight() != mThumbnailHeight) {
- throw new IllegalArgumentException("Bad thumbnail size: got "
- + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
- + mThumbnailWidth + "x" + mThumbnailHeight);
- }
- if (intent.getSelector() != null) {
- intent.setSelector(null);
- }
- if (intent.getSourceBounds() != null) {
- intent.setSourceBounds(null);
- }
- if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
- if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
- // The caller has added this as an auto-remove task... that makes no
- // sense, so turn off auto-remove.
- intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
- }
- }
- final ActivityInfo ainfo = AppGlobals.getPackageManager().getActivityInfo(comp,
- STOCK_PM_FLAGS, UserHandle.getUserId(callingUid));
- if (ainfo.applicationInfo.uid != callingUid) {
- throw new SecurityException(
- "Can't add task for another application: target uid="
- + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
- }
-
- final ActivityStack stack = r.getStack();
- final TaskRecord task = stack.createTaskRecord(
- mStackSupervisor.getNextTaskIdForUserLocked(r.userId), ainfo, intent,
- null /* voiceSession */, null /* voiceInteractor */, !ON_TOP);
- if (!mRecentTasks.addToBottom(task)) {
- // The app has too many tasks already and we can't add any more
- stack.removeTask(task, "addAppTask", REMOVE_TASK_MODE_DESTROYING);
- return INVALID_TASK_ID;
- }
- task.lastTaskDescription.copyFrom(description);
-
- // TODO: Send the thumbnail to WM to store it.
-
- return task.taskId;
- }
- } finally {
- Binder.restoreCallingIdentity(callingIdent);
- }
- }
-
- @Override
- public Point getAppTaskThumbnailSize() {
- synchronized (this) {
- return new Point(mThumbnailWidth, mThumbnailHeight);
- }
- }
-
- @Override
- public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
- synchronized (this) {
- ActivityRecord r = ActivityRecord.isInStackLocked(token);
- if (r != null) {
- r.setTaskDescription(td);
- final TaskRecord task = r.getTask();
- task.updateTaskDescription();
- mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
- }
- }
- }
-
- @Override
public void setTaskResizeable(int taskId, int resizeableMode) {
- synchronized (this) {
- final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
- taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
- if (task == null) {
- Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
- return;
- }
- task.setResizeMode(resizeableMode);
- }
+ mActivityTaskManager.setTaskResizeable(taskId, resizeableMode);
+ }
+
+ @Override
+ public ActivityManager.TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
+ return mActivityTaskManager.getTaskSnapshot(taskId, reducedResolution);
}
@Override
public void resizeTask(int taskId, Rect bounds, int resizeMode) {
- enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
- long ident = Binder.clearCallingIdentity();
- try {
- synchronized (this) {
- TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
- if (task == null) {
- Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
- return;
- }
- // Place the task in the right stack if it isn't there already based on
- // the requested bounds.
- // The stack transition logic is:
- // - a null bounds on a freeform task moves that task to fullscreen
- // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
- // that task to freeform
- // - otherwise the task is not moved
- ActivityStack stack = task.getStack();
- if (!task.getWindowConfiguration().canResizeTask()) {
- throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
- }
- if (bounds == null && stack.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
- stack = stack.getDisplay().getOrCreateStack(
- WINDOWING_MODE_FULLSCREEN, stack.getActivityType(), ON_TOP);
- } else if (bounds != null && stack.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
- stack = stack.getDisplay().getOrCreateStack(
- WINDOWING_MODE_FREEFORM, stack.getActivityType(), ON_TOP);
- }
-
- // Reparent the task to the right stack if necessary
- boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
- if (stack != task.getStack()) {
- // Defer resume until the task is resized below
- task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
- DEFER_RESUME, "resizeTask");
- preserveWindow = false;
- }
-
- // After reparenting (which only resizes the task to the stack bounds), resize the
- // task to the actual bounds provided
- task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
- }
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
+ mActivityTaskManager.resizeTask(taskId, bounds, resizeMode);
}
@Override
public Rect getTaskBounds(int taskId) {
- enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
- long ident = Binder.clearCallingIdentity();
- Rect rect = new Rect();
- try {
- synchronized (this) {
- final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
- MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
- if (task == null) {
- Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
- return rect;
- }
- if (task.getStack() != null) {
- // Return the bounds from window manager since it will be adjusted for various
- // things like the presense of a docked stack for tasks that aren't resizeable.
- task.getWindowContainerBounds(rect);
- } else {
- // Task isn't in window manager yet since it isn't associated with a stack.
- // Return the persist value from activity manager
- if (!task.matchParentBounds()) {
- rect.set(task.getBounds());
- } else if (task.mLastNonFullscreenBounds != null) {
- rect.set(task.mLastNonFullscreenBounds);
- }
- }
- }
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- return rect;
- }
-
- @Override
- public void cancelTaskWindowTransition(int taskId) {
- enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
- "cancelTaskWindowTransition()");
- final long ident = Binder.clearCallingIdentity();
- try {
- synchronized (this) {
- final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
- MATCH_TASK_IN_STACKS_ONLY);
- if (task == null) {
- Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
- return;
- }
- task.cancelWindowTransition();
- }
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
-
- @Override
- public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
- enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
- final long ident = Binder.clearCallingIdentity();
- try {
- final TaskRecord task;
- synchronized (this) {
- task = mStackSupervisor.anyTaskForIdLocked(taskId,
- MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
- if (task == null) {
- Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
- return null;
- }
- }
- // Don't call this while holding the lock as this operation might hit the disk.
- return task.getSnapshot(reducedResolution);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
-
- @Override
- public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
- userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
- userId, false, ALLOW_FULL_ONLY, "getTaskDescriptionIcon", null);
-
- final File passedIconFile = new File(filePath);
- final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
- passedIconFile.getName());
- if (!legitIconFile.getPath().equals(filePath)
- || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
- throw new IllegalArgumentException("Bad file path: " + filePath
- + " passed for userId " + userId);
- }
- return mRecentTasks.getTaskDescriptionIcon(filePath);
- }
-
- @Override
- public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
- throws RemoteException {
- final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(opts);
- final ActivityOptions activityOptions = safeOptions != null
- ? safeOptions.getOptions(mStackSupervisor)
- : null;
- if (activityOptions == null
- || activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE
- || activityOptions.getCustomInPlaceResId() == 0) {
- throw new IllegalArgumentException("Expected in-place ActivityOption " +
- "with valid animation");
- }
- mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
- mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
- activityOptions.getCustomInPlaceResId());
- mWindowManager.executeAppTransition();
+ return mActivityTaskManager.getTaskBounds(taskId);
}
@Override
public void removeStack(int stackId) {
- enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()");
- synchronized (this) {
- final long ident = Binder.clearCallingIdentity();
- try {
- final ActivityStack stack = mStackSupervisor.getStack(stackId);
- if (stack == null) {
- Slog.w(TAG, "removeStack: No stack with id=" + stackId);
- return;
- }
- if (!stack.isActivityTypeStandardOrUndefined()) {
- throw new IllegalArgumentException(
- "Removing non-standard stack is not allowed.");
- }
- mStackSupervisor.removeStack(stack);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
- }
-
- @Override
- public void moveStackToDisplay(int stackId, int displayId) {
- enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
-
- synchronized (this) {
- final long ident = Binder.clearCallingIdentity();
- try {
- if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
- + " to displayId=" + displayId);
- mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
+ mActivityTaskManager.removeStack(stackId);
}
@Override
public boolean removeTask(int taskId) {
- enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeTask()");
- synchronized (this) {
- final long ident = Binder.clearCallingIdentity();
- try {
- return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS,
- "remove-task");
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
+ return mActivityTaskManager.removeTask(taskId);
}
- /**
- * TODO: Add mController hook
- */
@Override
public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
- enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
-
- if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
- synchronized(this) {
- moveTaskToFrontLocked(taskId, flags, SafeActivityOptions.fromBundle(bOptions),
- false /* fromRecents */);
- }
- }
-
- void moveTaskToFrontLocked(int taskId, int flags, SafeActivityOptions options,
- boolean fromRecents) {
-
- if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
- Binder.getCallingUid(), -1, -1, "Task to front")) {
- SafeActivityOptions.abort(options);
- return;
- }
- final long origId = Binder.clearCallingIdentity();
- try {
- final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
- if (task == null) {
- Slog.d(TAG, "Could not find task for id: "+ taskId);
- return;
- }
- if (mLockTaskController.isLockTaskModeViolation(task)) {
- Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
- return;
- }
- ActivityOptions realOptions = options != null
- ? options.getOptions(mStackSupervisor)
- : null;
- mStackSupervisor.findTaskToMoveToFront(task, flags, realOptions, "moveTaskToFront",
- false /* forceNonResizable */);
-
- final ActivityRecord topActivity = task.getTopActivity();
- if (topActivity != null) {
-
- // We are reshowing a task, use a starting window to hide the initial draw delay
- // so the transition can start earlier.
- topActivity.showStartingWindow(null /* prev */, false /* newTask */,
- true /* taskSwitch */, fromRecents);
- }
- } finally {
- Binder.restoreCallingIdentity(origId);
- }
- SafeActivityOptions.abort(options);
+ mActivityTaskManager.moveTaskToFront(taskId, flags, bOptions);
}
/**
@@ -10995,92 +9439,7 @@
*/
@Override
public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
- enforceNotIsolatedCaller("moveActivityTaskToBack");
- synchronized(this) {
- final long origId = Binder.clearCallingIdentity();
- try {
- int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
- final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
- if (task != null) {
- return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
- }
- } finally {
- Binder.restoreCallingIdentity(origId);
- }
- }
- return false;
- }
-
- @Override
- public void moveTaskBackwards(int task) {
- enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
- "moveTaskBackwards()");
-
- synchronized(this) {
- if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
- Binder.getCallingUid(), -1, -1, "Task backwards")) {
- return;
- }
- final long origId = Binder.clearCallingIdentity();
- moveTaskBackwardsLocked(task);
- Binder.restoreCallingIdentity(origId);
- }
- }
-
- private final void moveTaskBackwardsLocked(int task) {
- Slog.e(TAG, "moveTaskBackwards not yet implemented!");
- }
-
- @Override
- public int createStackOnDisplay(int displayId) throws RemoteException {
- enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
- synchronized (this) {
- final ActivityDisplay display =
- mStackSupervisor.getActivityDisplayOrCreateLocked(displayId);
- if (display == null) {
- return INVALID_STACK_ID;
- }
- // TODO(multi-display): Have the caller pass in the windowing mode and activity type.
- final ActivityStack stack = display.createStack(
- WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD,
- ON_TOP);
- return (stack != null) ? stack.mStackId : INVALID_STACK_ID;
- }
- }
-
- @Override
- public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
- synchronized (this) {
- final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
- if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
- return stack.mDisplayId;
- }
- return DEFAULT_DISPLAY;
- }
- }
-
- @Override
- public void exitFreeformMode(IBinder token) throws RemoteException {
- synchronized (this) {
- long ident = Binder.clearCallingIdentity();
- try {
- final ActivityRecord r = ActivityRecord.forTokenLocked(token);
- if (r == null) {
- throw new IllegalArgumentException(
- "exitFreeformMode: No activity record matching token=" + token);
- }
-
- final ActivityStack stack = r.getStack();
- if (stack == null || !stack.inFreeformWindowingMode()) {
- throw new IllegalStateException(
- "exitFreeformMode: You can only go fullscreen from freeform.");
- }
-
- stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
+ return mActivityTaskManager.moveActivityTaskToBack(token, nonRoot);
}
@Override
@@ -11088,77 +9447,17 @@
mActivityTaskManager.moveTaskToStack(taskId, stackId, toTop);
}
- /**
- * Dismisses split-screen multi-window mode.
- * @param toTop If true the current primary split-screen stack will be placed or left on top.
- */
@Override
- public void dismissSplitScreenMode(boolean toTop) {
- enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()");
- final long ident = Binder.clearCallingIdentity();
- try {
- synchronized (this) {
- final ActivityStack stack =
- mStackSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
- if (stack == null) {
- Slog.w(TAG, "dismissSplitScreenMode: primary split-screen stack not found.");
- return;
- }
-
- if (toTop) {
- // Caller wants the current split-screen primary stack to be the top stack after
- // it goes fullscreen, so move it to the front.
- stack.moveToFront("dismissSplitScreenMode");
- } else if (mStackSupervisor.isFocusedStack(stack)) {
- // In this case the current split-screen primary stack shouldn't be the top
- // stack after it goes fullscreen, but it current has focus, so we move the
- // focus to the top-most split-screen secondary stack next to it.
- final ActivityStack otherStack = stack.getDisplay().getTopStackInWindowingMode(
- WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
- if (otherStack != null) {
- otherStack.moveToFront("dismissSplitScreenMode_other");
- }
- }
-
- stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
- }
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
+ public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
+ boolean preserveWindows, boolean animate, int animationDuration) {
+ mActivityTaskManager.resizeStack(stackId, destBounds, allowResizeInDockedMode,
+ preserveWindows, animate, animationDuration);
}
- /**
- * Dismisses Pip
- * @param animate True if the dismissal should be animated.
- * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
- * default animation duration should be used.
- */
@Override
- public void dismissPip(boolean animate, int animationDuration) {
- enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
- final long ident = Binder.clearCallingIdentity();
- try {
- synchronized (this) {
- final PinnedActivityStack stack =
- mStackSupervisor.getDefaultDisplay().getPinnedStack();
- if (stack == null) {
- Slog.w(TAG, "dismissPip: pinned stack not found.");
- return;
- }
- if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
- throw new IllegalArgumentException("Stack: " + stack
- + " doesn't support animated resize.");
- }
- if (animate) {
- stack.animateResizePinnedStack(null /* sourceHintBounds */,
- null /* destBounds */, animationDuration, false /* fromFullscreen */);
- } else {
- mStackSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
- }
- }
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
+ public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
+ int userId) {
+ return mActivityTaskManager.getRecentTasks(maxNum, flags, userId);
}
/**
@@ -11172,150 +9471,30 @@
*/
@Override
public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
- enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
- "moveTopActivityToPinnedStack()");
- synchronized (this) {
- if (!mSupportsPictureInPicture) {
- throw new IllegalStateException("moveTopActivityToPinnedStack:"
- + "Device doesn't support picture-in-picture mode");
- }
-
- long ident = Binder.clearCallingIdentity();
- try {
- return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
- }
-
- @Override
- public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
- boolean preserveWindows, boolean animate, int animationDuration) {
- mActivityTaskManager.resizeStack(stackId, destBounds, allowResizeInDockedMode,
- preserveWindows, animate, animationDuration);
+ return mActivityTaskManager.moveTopActivityToPinnedStack(stackId, bounds);
}
@Override
public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
Rect tempDockedTaskInsetBounds,
Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
- enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeDockedStack()");
- long ident = Binder.clearCallingIdentity();
- try {
- synchronized (this) {
- mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
- tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
- PRESERVE_WINDOWS);
- }
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
+ mActivityTaskManager.resizeDockedStack(dockedBounds, tempDockedTaskBounds,
+ tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds);
}
@Override
- public void setSplitScreenResizing(boolean resizing) {
- enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setSplitScreenResizing()");
- final long ident = Binder.clearCallingIdentity();
- try {
- synchronized (this) {
- mStackSupervisor.setSplitScreenResizing(resizing);
- }
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
-
- @Override
- public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
- enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()");
- final long ident = Binder.clearCallingIdentity();
- try {
- synchronized (this) {
- mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
- }
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
-
- /**
- * Try to place task to provided position. The final position might be different depending on
- * current user and stacks state. The task will be moved to target stack if it's currently in
- * different stack.
- */
- @Override
public void positionTaskInStack(int taskId, int stackId, int position) {
- enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
- synchronized (this) {
- long ident = Binder.clearCallingIdentity();
- try {
- if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
- + taskId + " in stackId=" + stackId + " at position=" + position);
- final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
- if (task == null) {
- throw new IllegalArgumentException("positionTaskInStack: no task for id="
- + taskId);
- }
-
- final ActivityStack stack = mStackSupervisor.getStack(stackId);
-
- if (stack == null) {
- throw new IllegalArgumentException("positionTaskInStack: no stack for id="
- + stackId);
- }
- if (!stack.isActivityTypeStandardOrUndefined()) {
- throw new IllegalArgumentException("positionTaskInStack: Attempt to change"
- + " the position of task " + taskId + " in/to non-standard stack");
- }
-
- // TODO: Have the callers of this API call a separate reparent method if that is
- // what they intended to do vs. having this method also do reparenting.
- if (task.getStack() == stack) {
- // Change position in current stack.
- stack.positionChildAt(task, position);
- } else {
- // Reparent to new stack.
- task.reparent(stack, position, REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE,
- !DEFER_RESUME, "positionTaskInStack");
- }
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
+ mActivityTaskManager.positionTaskInStack(taskId, stackId, position);
}
@Override
public List<StackInfo> getAllStackInfos() {
- enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
- long ident = Binder.clearCallingIdentity();
- try {
- synchronized (this) {
- return mStackSupervisor.getAllStackInfosLocked();
- }
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
-
- @Override
- public StackInfo getStackInfo(int windowingMode, int activityType) {
- enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
- long ident = Binder.clearCallingIdentity();
- try {
- synchronized (this) {
- return mStackSupervisor.getStackInfo(windowingMode, activityType);
- }
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
+ return mActivityTaskManager.getAllStackInfos();
}
@Override
public int getTaskForActivity(IBinder token, boolean onlyRoot) {
- synchronized(this) {
- return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
- }
+ return mActivityTaskManager.getTaskForActivity(token, onlyRoot);
}
@Override
@@ -11344,156 +9523,18 @@
}
@Override
- public void updateLockTaskFeatures(int userId, int flags) {
- final int callingUid = Binder.getCallingUid();
- if (callingUid != 0 && callingUid != SYSTEM_UID) {
- enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
- "updateLockTaskFeatures()");
- }
- synchronized (this) {
- if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Allowing features " + userId + ":0x" +
- Integer.toHexString(flags));
- mLockTaskController.updateLockTaskFeatures(userId, flags);
- }
- }
-
- private void startLockTaskModeLocked(@Nullable TaskRecord task, boolean isSystemCaller) {
- if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
- if (task == null || task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
- return;
- }
-
- final ActivityStack stack = mStackSupervisor.getFocusedStack();
- if (stack == null || task != stack.topTask()) {
- throw new IllegalArgumentException("Invalid task, not in foreground");
- }
-
- // {@code isSystemCaller} is used to distinguish whether this request is initiated by the
- // system or a specific app.
- // * System-initiated requests will only start the pinned mode (screen pinning)
- // * App-initiated requests
- // - will put the device in fully locked mode (LockTask), if the app is whitelisted
- // - will start the pinned mode, otherwise
- final int callingUid = Binder.getCallingUid();
- long ident = Binder.clearCallingIdentity();
- try {
- // When a task is locked, dismiss the pinned stack if it exists
- mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
-
- mLockTaskController.startLockTaskMode(task, isSystemCaller, callingUid);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
-
- @Override
- public void startLockTaskModeByToken(IBinder token) {
- synchronized (this) {
- final ActivityRecord r = ActivityRecord.forTokenLocked(token);
- if (r == null) {
- return;
- }
- startLockTaskModeLocked(r.getTask(), false /* isSystemCaller */);
- }
- }
-
- @Override
- public void startSystemLockTaskMode(int taskId) throws RemoteException {
- enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
- // This makes inner call to look as if it was initiated by system.
- long ident = Binder.clearCallingIdentity();
- try {
- synchronized (this) {
- final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
-
- // When starting lock task mode the stack must be in front and focused
- task.getStack().moveToFront("startSystemLockTaskMode");
- startLockTaskModeLocked(task, true /* isSystemCaller */);
- }
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
-
- @Override
- public void stopLockTaskModeByToken(IBinder token) {
- synchronized (this) {
- final ActivityRecord r = ActivityRecord.forTokenLocked(token);
- if (r == null) {
- return;
- }
- stopLockTaskModeInternal(r.getTask(), 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.
- */
- @Override
- public void stopSystemLockTaskMode() throws RemoteException {
- enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode");
- stopLockTaskModeInternal(null, true /* isSystemCaller */);
- }
-
- private void stopLockTaskModeInternal(@Nullable TaskRecord task, boolean isSystemCaller) {
- final int callingUid = Binder.getCallingUid();
- long ident = Binder.clearCallingIdentity();
- try {
- synchronized (this) {
- mLockTaskController.stopLockTaskMode(task, isSystemCaller, callingUid);
- }
- // Launch in-call UI if a call is ongoing. This is necessary to allow stopping the lock
- // task and jumping straight into a call in the case of emergency call back.
- TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
- if (tm != null) {
- tm.showInCallScreen(false);
- }
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
-
- @Override
public boolean isInLockTaskMode() {
- return getLockTaskModeState() != LOCK_TASK_MODE_NONE;
+ return mActivityTaskManager.isInLockTaskMode();
}
@Override
public int getLockTaskModeState() {
- synchronized (this) {
- return mLockTaskController.getLockTaskModeState();
- }
+ return mActivityTaskManager.getLockTaskModeState();
}
@Override
- public void showLockTaskEscapeMessage(IBinder token) {
- synchronized (this) {
- final ActivityRecord r = ActivityRecord.forTokenLocked(token);
- if (r == null) {
- return;
- }
- mLockTaskController.showLockTaskToast();
- }
- }
-
- @Override
- public void setDisablePreviewScreenshots(IBinder token, boolean disable)
- throws RemoteException {
- synchronized (this) {
- 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);
- }
- }
+ public void startSystemLockTaskMode(int taskId) throws RemoteException {
+ mActivityTaskManager.startSystemLockTaskMode(taskId);
}
// =========================================================
@@ -12893,17 +10934,7 @@
}
public void unhandledBack() {
- enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
- "unhandledBack()");
-
- synchronized(this) {
- final long origId = Binder.clearCallingIdentity();
- try {
- getFocusedStack().unhandledBackLocked();
- } finally {
- Binder.restoreCallingIdentity(origId);
- }
- }
+ mActivityTaskManager.unhandledBack();
}
public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
@@ -12970,12 +11001,6 @@
: UsageEvents.Event.SCREEN_NON_INTERACTIVE);
}
- void reportCurKeyguardUsageEventLocked() {
- reportGlobalUsageEventLocked(mKeyguardShown
- ? UsageEvents.Event.KEYGUARD_SHOWN
- : UsageEvents.Event.KEYGUARD_HIDDEN);
- }
-
void onWakefulnessChanged(int wakefulness) {
synchronized(this) {
boolean wasAwake = mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
@@ -13045,22 +11070,6 @@
mRecentTasks.notifyTaskPersisterLocked(task, flush);
}
- /**
- * Notifies all listeners when the pinned stack animation starts.
- */
- @Override
- public void notifyPinnedStackAnimationStarted() {
- mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
- }
-
- /**
- * Notifies all listeners when the pinned stack animation ends.
- */
- @Override
- public void notifyPinnedStackAnimationEnded() {
- mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
- }
-
@Override
public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
@@ -13096,21 +11105,6 @@
return timedout;
}
- public final void activitySlept(IBinder token) {
- if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
-
- final long origId = Binder.clearCallingIdentity();
-
- synchronized (this) {
- final ActivityRecord r = ActivityRecord.isInStackLocked(token);
- if (r != null) {
- mStackSupervisor.activitySleptLocked(r);
- }
- }
-
- Binder.restoreCallingIdentity(origId);
- }
-
@GuardedBy("this")
void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
Slog.d(TAG, "<<< startRunningVoiceLocked()");
@@ -13132,28 +11126,8 @@
@Override
public void setLockScreenShown(boolean keyguardShowing, boolean aodShowing,
int secondaryDisplayShowing) {
- if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException("Requires permission "
- + android.Manifest.permission.DEVICE_POWER);
- }
-
- synchronized(this) {
- long ident = Binder.clearCallingIdentity();
- if (mKeyguardShown != keyguardShowing) {
- mKeyguardShown = keyguardShowing;
- reportCurKeyguardUsageEventLocked();
- }
- try {
- mKeyguardController.setKeyguardShown(keyguardShowing, aodShowing,
- secondaryDisplayShowing);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
-
- mHandler.obtainMessage(DISPATCH_SCREEN_KEYGUARD_MSG, keyguardShowing ? 1 : 0, 0)
- .sendToTarget();
+ mActivityTaskManager.setLockScreenShown(
+ keyguardShowing, aodShowing, secondaryDisplayShowing);
}
@Override
@@ -13644,266 +11618,6 @@
return true;
}
- @Override
- public Bundle getAssistContextExtras(int requestType) {
- PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
- null, null, true /* focused */, true /* newSessionId */,
- UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
- if (pae == null) {
- return null;
- }
- synchronized (pae) {
- while (!pae.haveResult) {
- try {
- pae.wait();
- } catch (InterruptedException e) {
- }
- }
- }
- synchronized (this) {
- buildAssistBundleLocked(pae, pae.result);
- mPendingAssistExtras.remove(pae);
- mUiHandler.removeCallbacks(pae);
- }
- return pae.extras;
- }
-
- @Override
- public boolean isAssistDataAllowedOnCurrentActivity() {
- int userId;
- synchronized (this) {
- final ActivityStack focusedStack = getFocusedStack();
- if (focusedStack == null || focusedStack.isActivityTypeAssistant()) {
- return false;
- }
-
- final ActivityRecord activity = focusedStack.getTopActivity();
- if (activity == null) {
- return false;
- }
- userId = activity.userId;
- }
- return !DevicePolicyCache.getInstance().getScreenCaptureDisabled(userId);
- }
-
- @Override
- public boolean showAssistFromActivity(IBinder token, Bundle args) {
- long ident = Binder.clearCallingIdentity();
- try {
- synchronized (this) {
- ActivityRecord caller = ActivityRecord.forTokenLocked(token);
- ActivityRecord top = getFocusedStack().getTopActivity();
- 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 requestAssistContextExtras(int requestType, IAssistDataReceiver receiver,
- Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
- return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
- activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
- PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
- }
-
- @Override
- public boolean requestAutofillData(IAssistDataReceiver receiver, Bundle receiverExtras,
- IBinder activityToken, int flags) {
- return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
- receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
- null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
- }
-
- private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
- IAssistDataReceiver receiver, Bundle receiverExtras, IBinder activityToken,
- boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
- int flags) {
- enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
- "enqueueAssistContext()");
-
- synchronized (this) {
- ActivityRecord activity = getFocusedStack().getTopActivity();
- if (activity == null) {
- Slog.w(TAG, "getAssistContextExtras failed: no top activity");
- return null;
- }
- if (activity.app == null || activity.app.thread == null) {
- Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
- return null;
- }
- if (focused) {
- if (activityToken != null) {
- ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
- if (activity != caller) {
- Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
- + " is not current top " + activity);
- return null;
- }
- }
- } else {
- activity = ActivityRecord.forTokenLocked(activityToken);
- if (activity == null) {
- Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
- + " couldn't be found");
- return null;
- }
- if (activity.app == null || activity.app.thread == null) {
- Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
- return null;
- }
- }
-
- PendingAssistExtras pae;
- Bundle extras = new Bundle();
- if (args != null) {
- extras.putAll(args);
- }
- extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
- extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
-
- pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
- userHandle);
- pae.isHome = activity.isActivityTypeHome();
-
- // Increment the sessionId if necessary
- if (newSessionId) {
- mViSessionId++;
- }
- try {
- activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
- mViSessionId, flags);
- mPendingAssistExtras.add(pae);
- mUiHandler.postDelayed(pae, timeout);
- } catch (RemoteException e) {
- Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
- return null;
- }
- return pae;
- }
- }
-
- void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
- IAssistDataReceiver receiver;
- synchronized (this) {
- mPendingAssistExtras.remove(pae);
- receiver = pae.receiver;
- }
- if (receiver != null) {
- // Caller wants result sent back to them.
- Bundle sendBundle = new Bundle();
- // At least return the receiver extras
- sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
- try {
- pae.receiver.onHandleAssistData(sendBundle);
- } catch (RemoteException e) {
- }
- }
- }
-
- private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
- if (result != null) {
- pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
- }
- if (pae.hint != null) {
- pae.extras.putBoolean(pae.hint, true);
- }
- }
-
- /** 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;
- synchronized (pae) {
- pae.result = extras;
- pae.structure = structure;
- pae.content = content;
- if (referrer != null) {
- pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
- }
- if (structure != null) {
- structure.setHomeActivity(pae.isHome);
- }
- pae.haveResult = true;
- pae.notifyAll();
- if (pae.intent == null && pae.receiver == null) {
- // Caller is just waiting for the result.
- return;
- }
- }
- // We are now ready to launch the assist activity.
- IAssistDataReceiver sendReceiver = null;
- Bundle sendBundle = null;
- synchronized (this) {
- buildAssistBundleLocked(pae, extras);
- boolean exists = mPendingAssistExtras.remove(pae);
- mUiHandler.removeCallbacks(pae);
- if (!exists) {
- // Timed out.
- return;
- }
-
- if ((sendReceiver=pae.receiver) != null) {
- // Caller wants result sent back to them.
- sendBundle = new Bundle();
- sendBundle.putBundle(ASSIST_KEY_DATA, pae.extras);
- sendBundle.putParcelable(ASSIST_KEY_STRUCTURE, pae.structure);
- sendBundle.putParcelable(ASSIST_KEY_CONTENT, pae.content);
- sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
- }
- }
- if (sendReceiver != null) {
- try {
- sendReceiver.onHandleAssistData(sendBundle);
- } catch (RemoteException e) {
- }
- return;
- }
-
- final long ident = Binder.clearCallingIdentity();
- try {
- if (TextUtils.equals(pae.intent.getAction(),
- android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
- pae.intent.putExtras(pae.extras);
- mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
- } else {
- pae.intent.replaceExtras(pae.extras);
- pae.intent.setFlags(FLAG_ACTIVITY_NEW_TASK
- | Intent.FLAG_ACTIVITY_SINGLE_TOP
- | Intent.FLAG_ACTIVITY_CLEAR_TOP);
- closeSystemDialogs("assist");
-
- try {
- mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
- } catch (ActivityNotFoundException e) {
- Slog.w(TAG, "No activity to handle assist action.", e);
- }
- }
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
-
- public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
- Bundle args) {
- return enqueueAssistContext(requestType, intent, hint, null, null, null,
- true /* focused */, true /* newSessionId */, userHandle, args,
- PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
- }
-
public void registerProcessObserver(IProcessObserver observer) {
enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
"registerProcessObserver()");
@@ -13969,101 +11683,6 @@
}
@Override
- public boolean convertFromTranslucent(IBinder token) {
- final long origId = Binder.clearCallingIdentity();
- try {
- synchronized (this) {
- final ActivityRecord r = ActivityRecord.isInStackLocked(token);
- if (r == null) {
- return false;
- }
- final boolean translucentChanged = r.changeWindowTranslucency(true);
- if (translucentChanged) {
- mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
- }
- mWindowManager.setAppFullscreen(token, true);
- return translucentChanged;
- }
- } finally {
- Binder.restoreCallingIdentity(origId);
- }
- }
-
- @Override
- public boolean convertToTranslucent(IBinder token, Bundle options) {
- SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(options);
- final long origId = Binder.clearCallingIdentity();
- try {
- synchronized (this) {
- final ActivityRecord r = ActivityRecord.isInStackLocked(token);
- if (r == null) {
- return false;
- }
- final TaskRecord task = r.getTask();
- int index = task.mActivities.lastIndexOf(r);
- if (index > 0) {
- ActivityRecord under = task.mActivities.get(index - 1);
- under.returningOptions = safeOptions != null ? safeOptions.getOptions(r) : null;
- }
- final boolean translucentChanged = r.changeWindowTranslucency(false);
- if (translucentChanged) {
- r.getStack().convertActivityToTranslucent(r);
- }
- mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
- mWindowManager.setAppFullscreen(token, false);
- return translucentChanged;
- }
- } finally {
- Binder.restoreCallingIdentity(origId);
- }
- }
-
- @Override
- public Bundle getActivityOptions(IBinder token) {
- final long origId = Binder.clearCallingIdentity();
- try {
- synchronized (this) {
- final ActivityRecord r = ActivityRecord.isInStackLocked(token);
- if (r != null) {
- final ActivityOptions activityOptions = r.takeOptionsLocked();
- return activityOptions == null ? null : activityOptions.toBundle();
- }
- return null;
- }
- } finally {
- Binder.restoreCallingIdentity(origId);
- }
- }
-
- @Override
- public void setImmersive(IBinder token, boolean immersive) {
- synchronized(this) {
- final ActivityRecord r = ActivityRecord.isInStackLocked(token);
- if (r == null) {
- throw new IllegalArgumentException();
- }
- r.immersive = immersive;
-
- // update associated state if we're frontmost
- if (r == mStackSupervisor.getResumedActivityLocked()) {
- if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
- applyUpdateLockStateLocked(r);
- }
- }
- }
-
- @Override
- public boolean isImmersive(IBinder token) {
- synchronized (this) {
- ActivityRecord r = ActivityRecord.isInStackLocked(token);
- if (r == null) {
- throw new IllegalArgumentException();
- }
- return r.immersive;
- }
- }
-
- @Override
public void setVrThread(int tid) {
enforceSystemHasVrFeature();
synchronized (this) {
@@ -14147,7 +11766,7 @@
* Check that we have the features required for VR-related API calls, and throw an exception if
* not.
*/
- private void enforceSystemHasVrFeature() {
+ void enforceSystemHasVrFeature() {
if (!mContext.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) {
throw new UnsupportedOperationException("VR mode not supported on this device!");
@@ -14207,44 +11826,6 @@
}
@Override
- public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
- enforceSystemHasVrFeature();
-
- final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
-
- ActivityRecord r;
- synchronized (this) {
- r = ActivityRecord.isInStackLocked(token);
- }
-
- if (r == null) {
- throw new IllegalArgumentException();
- }
-
- int err;
- if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
- VrManagerInternal.NO_ERROR) {
- return err;
- }
-
- // Clear the binder calling uid since this path may call moveToTask().
- final long callingId = Binder.clearCallingIdentity();
- try {
- synchronized(this) {
- r.requestedVrComponent = (enabled) ? packageName : null;
-
- // Update associated state if this activity is currently focused
- if (r == mStackSupervisor.getResumedActivityLocked()) {
- applyUpdateVrModeLocked(r);
- }
- return 0;
- }
- } finally {
- Binder.restoreCallingIdentity(callingId);
- }
- }
-
- @Override
public boolean isVrModePackageEnabled(ComponentName packageName) {
enforceSystemHasVrFeature();
@@ -14255,11 +11836,7 @@
}
public boolean isTopActivityImmersive() {
- enforceNotIsolatedCaller("startActivity");
- synchronized (this) {
- ActivityRecord r = getFocusedStack().topRunningActivityLocked();
- return (r != null) ? r.immersive : false;
- }
+ return mActivityTaskManager.isTopActivityImmersive();
}
/**
@@ -14271,13 +11848,7 @@
@Override
public boolean isTopOfTask(IBinder token) {
- synchronized (this) {
- ActivityRecord r = ActivityRecord.isInStackLocked(token);
- if (r == null) {
- throw new IllegalArgumentException();
- }
- return r.getTask().getTopActivity() == r;
- }
+ return mActivityTaskManager.isTopOfTask(token);
}
@Override
@@ -14843,7 +12414,7 @@
PackageManager.FEATURE_CANT_SAVE_STATE);
mLocalDeviceIdleController
= LocalServices.getService(DeviceIdleController.LocalService.class);
- mAssistUtils = new AssistUtils(mContext);
+ mActivityTaskManager.onSystemReady();
mVrController.onSystemReady();
// Make sure we have the current profile info, since it is needed for security checks.
mUserController.onSystemReady();
@@ -22006,19 +19577,7 @@
@Override
public StackInfo getFocusedStackInfo() throws RemoteException {
- enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
- long ident = Binder.clearCallingIdentity();
- try {
- synchronized (this) {
- ActivityStack focusedStack = getFocusedStack();
- if (focusedStack != null) {
- return mStackSupervisor.getStackInfo(focusedStack.mStackId);
- }
- return null;
- }
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
+ return mActivityTaskManager.getFocusedStackInfo();
}
public Configuration getConfiguration() {
@@ -22032,37 +19591,7 @@
@Override
public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
- enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
- synchronized (this) {
- mSuppressResizeConfigChanges = suppress;
- }
- }
-
- /**
- * NOTE: For the pinned stack, this method is usually called after the bounds animation has
- * animated the stack to the fullscreen, but can also be called if we are relaunching an
- * activity and clearing the task at the same time.
- */
- @Override
- // TODO: API should just be about changing windowing modes...
- public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
- enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
- "moveTasksToFullscreenStack()");
- synchronized (this) {
- final long origId = Binder.clearCallingIdentity();
- try {
- final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
- if (stack != null){
- if (!stack.isActivityTypeStandardOrUndefined()) {
- throw new IllegalArgumentException(
- "You can't move tasks from non-standard stacks.");
- }
- mStackSupervisor.moveTasksToFullscreenStackLocked(stack, onTop);
- }
- } finally {
- Binder.restoreCallingIdentity(origId);
- }
- }
+ mActivityTaskManager.suppressResizeConfigChanges(suppress);
}
@Override
@@ -22126,32 +19655,7 @@
@Override
public boolean updateConfiguration(Configuration values) {
- enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
-
- synchronized(this) {
- if (values == null && mWindowManager != null) {
- // sentinel: fetch the current configuration from the window manager
- values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
- }
-
- if (mWindowManager != null) {
- // Update OOM levels based on display size.
- mProcessList.applyDisplaySize(mWindowManager);
- }
-
- final long origId = Binder.clearCallingIdentity();
- try {
- if (values != null) {
- Settings.System.clearConfiguration(values);
- }
- updateConfigurationLocked(values, null, false, false /* persistent */,
- UserHandle.USER_NULL, false /* deferResume */,
- mTmpUpdateConfigurationResult);
- return mTmpUpdateConfigurationResult.changes != 0;
- } finally {
- Binder.restoreCallingIdentity(origId);
- }
- }
+ return mActivityTaskManager.updateConfiguration(values);
}
void updateUserConfigurationLocked() {
@@ -22194,9 +19698,9 @@
* @param userId is only used when persistent parameter is set to true to persist configuration
* for that particular user
*/
- private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
+ boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
boolean initLocale, boolean persistent, int userId, boolean deferResume,
- UpdateConfigurationResult result) {
+ ActivityTaskManagerService.UpdateConfigurationResult result) {
int changes = 0;
boolean kept = true;
@@ -22375,45 +19879,6 @@
return changes;
}
- @Override
- public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
- enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
-
- synchronized (this) {
- // Check if display is initialized in AM.
- if (!mStackSupervisor.isDisplayAdded(displayId)) {
- // Call might come when display is not yet added or has already been removed.
- if (DEBUG_CONFIGURATION) {
- Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
- + displayId);
- }
- return false;
- }
-
- if (values == null && mWindowManager != null) {
- // sentinel: fetch the current configuration from the window manager
- values = mWindowManager.computeNewConfiguration(displayId);
- }
-
- if (mWindowManager != null) {
- // Update OOM levels based on display size.
- mProcessList.applyDisplaySize(mWindowManager);
- }
-
- final long origId = Binder.clearCallingIdentity();
- try {
- if (values != null) {
- Settings.System.clearConfiguration(values);
- }
- updateDisplayOverrideConfigurationLocked(values, null /* starting */,
- false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
- return mTmpUpdateConfigurationResult.changes != 0;
- } finally {
- Binder.restoreCallingIdentity(origId);
- }
- }
- }
-
boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
boolean deferResume, int displayId) {
return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
@@ -22424,9 +19889,9 @@
* Updates override configuration specific for the selected display. If no config is provided,
* new one will be computed in WM based on current display info.
*/
- private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
+ boolean updateDisplayOverrideConfigurationLocked(Configuration values,
ActivityRecord starting, boolean deferResume, int displayId,
- UpdateConfigurationResult result) {
+ ActivityTaskManagerService.UpdateConfigurationResult result) {
int changes = 0;
boolean kept = true;
@@ -22567,48 +20032,12 @@
}
@Override
- public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
- synchronized (this) {
- ActivityRecord srec = ActivityRecord.forTokenLocked(token);
- if (srec != null) {
- return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
- }
- }
- return false;
- }
-
- public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
- Intent resultData) {
-
- synchronized (this) {
- final ActivityRecord r = ActivityRecord.forTokenLocked(token);
- if (r != null) {
- return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
- }
- return false;
- }
- }
-
public int getLaunchedFromUid(IBinder activityToken) {
- ActivityRecord srec;
- synchronized (this) {
- srec = ActivityRecord.forTokenLocked(activityToken);
- }
- if (srec == null) {
- return -1;
- }
- return srec.launchedFromUid;
+ return mActivityTaskManager.getLaunchedFromUid(activityToken);
}
public String getLaunchedFromPackage(IBinder activityToken) {
- ActivityRecord srec;
- synchronized (this) {
- srec = ActivityRecord.forTokenLocked(activityToken);
- }
- if (srec == null) {
- return null;
- }
- return srec.launchedFromPackage;
+ return mActivityTaskManager.getLaunchedFromPackage(activityToken);
}
// =========================================================
@@ -25563,7 +22992,7 @@
}
}
- private void clearProfilerLocked() {
+ void clearProfilerLocked() {
if (mProfilerInfo !=null && mProfilerInfo.profileFd != null) {
try {
mProfilerInfo.profileFd.close();
@@ -26210,7 +23639,7 @@
@Override
public int startActivityAsUser(IApplicationThread caller, String callerPacakge,
Intent intent, Bundle options, int userId) {
- return ActivityManagerService.this.startActivityAsUser(
+ return ActivityManagerService.this.mActivityTaskManager.startActivityAsUser(
caller, callerPacakge, intent,
intent.resolveTypeIfNeeded(mContext.getContentResolver()),
null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, options, userId,
@@ -26494,7 +23923,8 @@
@Override
public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
- ActivityManagerService.this.cancelRecentsAnimation(restoreHomeStackPosition);
+ ActivityManagerService.this.mActivityTaskManager.cancelRecentsAnimation(
+ restoreHomeStackPosition);
}
@Override
@@ -26634,21 +24064,6 @@
}
/**
- * Return the user id of the last resumed activity.
- */
- @Override
- public @UserIdInt int getLastResumedActivityUserId() {
- enforceCallingPermission(
- permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
- synchronized (this) {
- if (mLastResumedActivity == null) {
- return mUserController.getCurrentUserId();
- }
- return mLastResumedActivity.userId;
- }
- }
-
- /**
* Kill processes for the user with id userId and that depend on the package named packageName
*/
@Override
@@ -26682,21 +24097,6 @@
}
@Override
- public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback,
- CharSequence message) throws RemoteException {
- if (message != null) {
- enforceCallingPermission(permission.SHOW_KEYGUARD_MESSAGE,
- "dismissKeyguard()");
- }
- final long callingId = Binder.clearCallingIdentity();
- try {
- mKeyguardController.dismissKeyguard(token, callback, message);
- } finally {
- Binder.restoreCallingIdentity(callingId);
- }
- }
-
- @Override
public int restartUserInBackground(final int userId) {
return mUserController.restartUser(userId, /* foreground */ false);
}
@@ -26815,87 +24215,4 @@
return mNmi != null;
}
}
-
- @Override
- public void setShowWhenLocked(IBinder token, boolean showWhenLocked)
- throws RemoteException {
- synchronized (this) {
- 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 setTurnScreenOn(IBinder token, boolean turnScreenOn) throws RemoteException {
- synchronized (this) {
- 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)
- throws RemoteException {
- enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
- "registerRemoteAnimations");
- definition.setCallingPid(Binder.getCallingPid());
- synchronized (this) {
- 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 registerRemoteAnimationForNextActivityStart(String packageName,
- RemoteAnimationAdapter adapter) throws RemoteException {
- enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
- "registerRemoteAnimationForNextActivityStart");
- adapter.setCallingPid(Binder.getCallingPid());
- synchronized (this) {
- final long origId = Binder.clearCallingIdentity();
- try {
- mActivityStartController.registerRemoteAnimationForNextActivityStart(packageName,
- adapter);
- } finally {
- Binder.restoreCallingIdentity(origId);
- }
- }
- }
-
- /** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */
- @Override
- public void alwaysShowUnsupportedCompileSdkWarning(ComponentName activity) {
- synchronized (this) {
- final long origId = Binder.clearCallingIdentity();
- try {
- mAppWarnings.alwaysShowUnsupportedCompileSdkWarning(activity);
- } finally {
- Binder.restoreCallingIdentity(origId);
- }
- }
- }
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index b443de8..0e78d06 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -479,12 +479,12 @@
options.setLockTaskEnabled(true);
}
if (mWaitOption) {
- result = mInterface.startActivityAndWait(null, null, intent, mimeType,
+ result = mTaskInterface.startActivityAndWait(null, null, intent, mimeType,
null, null, 0, mStartFlags, profilerInfo,
options != null ? options.toBundle() : null, mUserId);
res = result.result;
} else {
- res = mInterface.startActivityAsUser(null, null, intent, mimeType,
+ res = mTaskInterface.startActivityAsUser(null, null, intent, mimeType,
null, null, 0, mStartFlags, profilerInfo,
options != null ? options.toBundle() : null, mUserId);
}
@@ -578,7 +578,7 @@
}
mRepeat--;
if (mRepeat > 0) {
- mInterface.unhandledBack();
+ mTaskInterface.unhandledBack();
}
} while (mRepeat > 0);
return 0;
@@ -2186,7 +2186,7 @@
int runSuppressResizeConfigChanges(PrintWriter pw) throws RemoteException {
boolean suppress = Boolean.valueOf(getNextArgRequired());
- mInterface.suppressResizeConfigChanges(suppress);
+ mTaskInterface.suppressResizeConfigChanges(suppress);
return 0;
}
@@ -2453,7 +2453,7 @@
int stackId = Integer.parseInt(stackIdStr);
String displayIdStr = getNextArgRequired();
int displayId = Integer.parseInt(displayIdStr);
- mInterface.moveStackToDisplay(stackId, displayId);
+ mTaskInterface.moveStackToDisplay(stackId, displayId);
return 0;
}
@@ -2467,7 +2467,7 @@
throw new RuntimeException(e.getMessage(), e);
}
- final int stackId = mInterface.createStackOnDisplay(displayId);
+ final int stackId = mTaskInterface.createStackOnDisplay(displayId);
if (stackId != INVALID_STACK_ID) {
// TODO: Need proper support if this is used by test...
// container.startActivity(intent);
@@ -2546,7 +2546,7 @@
getErrPrintWriter().println("Error: invalid input bounds");
return -1;
}
- mInterface.resizeDockedStack(bounds, taskBounds, null, null, null);
+ mTaskInterface.resizeDockedStack(bounds, taskBounds, null, null, null);
return 0;
}
@@ -2566,12 +2566,12 @@
String positionStr = getNextArgRequired();
int position = Integer.parseInt(positionStr);
- mInterface.positionTaskInStack(taskId, stackId, position);
+ mTaskInterface.positionTaskInStack(taskId, stackId, position);
return 0;
}
int runStackList(PrintWriter pw) throws RemoteException {
- List<ActivityManager.StackInfo> stacks = mInterface.getAllStackInfos();
+ List<ActivityManager.StackInfo> stacks = mTaskInterface.getAllStackInfos();
for (ActivityManager.StackInfo info : stacks) {
pw.println(info);
}
@@ -2581,7 +2581,7 @@
int runStackInfo(PrintWriter pw) throws RemoteException {
int windowingMode = Integer.parseInt(getNextArgRequired());
int activityType = Integer.parseInt(getNextArgRequired());
- ActivityManager.StackInfo info = mInterface.getStackInfo(windowingMode, activityType);
+ ActivityManager.StackInfo info = mTaskInterface.getStackInfo(windowingMode, activityType);
pw.println(info);
return 0;
}
@@ -2589,7 +2589,7 @@
int runStackRemove(PrintWriter pw) throws RemoteException {
String stackIdStr = getNextArgRequired();
int stackId = Integer.parseInt(stackIdStr);
- mInterface.removeStack(stackId);
+ mTaskInterface.removeStack(stackId);
return 0;
}
@@ -2601,7 +2601,7 @@
return -1;
}
- if (!mInterface.moveTopActivityToPinnedStack(stackId, bounds)) {
+ if (!mTaskInterface.moveTopActivityToPinnedStack(stackId, bounds)) {
getErrPrintWriter().println("Didn't move top activity to pinned stack.");
return -1;
}
@@ -2647,12 +2647,12 @@
int runTaskLock(PrintWriter pw) throws RemoteException {
String taskIdStr = getNextArgRequired();
if (taskIdStr.equals("stop")) {
- mInterface.stopSystemLockTaskMode();
+ mTaskInterface.stopSystemLockTaskMode();
} else {
int taskId = Integer.parseInt(taskIdStr);
- mInterface.startSystemLockTaskMode(taskId);
+ mTaskInterface.startSystemLockTaskMode(taskId);
}
- pw.println("Activity manager is " + (mInterface.isInLockTaskMode() ? "" : "not ") +
+ pw.println("Activity manager is " + (mTaskInterface.isInLockTaskMode() ? "" : "not ") +
"in lockTaskMode");
return 0;
}
@@ -2662,7 +2662,7 @@
final int taskId = Integer.parseInt(taskIdStr);
final String resizeableStr = getNextArgRequired();
final int resizeableMode = Integer.parseInt(resizeableStr);
- mInterface.setTaskResizeable(taskId, resizeableMode);
+ mTaskInterface.setTaskResizeable(taskId, resizeableMode);
return 0;
}
@@ -2681,7 +2681,7 @@
void taskResize(int taskId, Rect bounds, int delay_ms, boolean pretendUserResize)
throws RemoteException {
final int resizeMode = pretendUserResize ? RESIZE_MODE_USER : RESIZE_MODE_SYSTEM;
- mInterface.resizeTask(taskId, bounds, resizeMode);
+ mTaskInterface.resizeTask(taskId, bounds, resizeMode);
try {
Thread.sleep(delay_ms);
} catch (InterruptedException e) {
@@ -2753,7 +2753,7 @@
int runTaskFocus(PrintWriter pw) throws RemoteException {
final int taskId = Integer.parseInt(getNextArgRequired());
pw.println("Setting focus to task " + taskId);
- mInterface.setFocusedTask(taskId);
+ mTaskInterface.setFocusedTask(taskId);
return 0;
}
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 696a184..35f3c09 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -1293,7 +1293,7 @@
}
boolean isKeyguardLocked = service.isKeyguardLocked();
- boolean isCurrentAppLocked = service.getLockTaskModeState() != LOCK_TASK_MODE_NONE;
+ boolean isCurrentAppLocked = service.mActivityTaskManager.getLockTaskModeState() != LOCK_TASK_MODE_NONE;
final ActivityDisplay display = getDisplay();
boolean hasPinnedStack = display != null && display.hasPinnedStack();
// Don't return early if !isNotLocked, since we want to throw an exception if the activity
@@ -2732,7 +2732,7 @@
}
void relaunchActivityLocked(boolean andResume, boolean preserveWindow) {
- if (service.mSuppressResizeConfigChanges && preserveWindow) {
+ if (service.mActivityTaskManager.mSuppressResizeConfigChanges && preserveWindow) {
configChangeFlags = 0;
return;
}
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 1486115..88589cc 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -2818,7 +2818,7 @@
/**
* Used from {@link ActivityStack#positionTask(TaskRecord, int)}.
- * @see ActivityManagerService#positionTaskInStack(int, int, int).
+ * @see ActivityTaskManagerService#positionTaskInStack(int, int, int).
*/
private void insertTaskAtPosition(TaskRecord task, int position) {
if (position >= mTaskHistory.size()) {
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 7a6f570..615edd5 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -4831,7 +4831,7 @@
sendPowerHintForLaunchStartIfNeeded(true /* forceSend */, targetActivity);
mActivityMetricsLogger.notifyActivityLaunching();
try {
- mService.moveTaskToFrontLocked(task.taskId, 0, options,
+ mService.mActivityTaskManager.moveTaskToFrontLocked(task.taskId, 0, options,
true /* fromRecents */);
} finally {
mActivityMetricsLogger.notifyActivityLaunched(START_TASK_TO_FRONT,
diff --git a/services/core/java/com/android/server/am/ActivityTaskManagerService.java b/services/core/java/com/android/server/am/ActivityTaskManagerService.java
index d7caa1a..c6edfe5 100644
--- a/services/core/java/com/android/server/am/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityTaskManagerService.java
@@ -16,31 +16,140 @@
package com.android.server.am;
+import static android.Manifest.permission.BIND_VOICE_INTERACTION;
+import static android.Manifest.permission.CHANGE_CONFIGURATION;
+import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS;
+import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
+import static android.Manifest.permission.READ_FRAME_BUFFER;
+import static android.Manifest.permission.REMOVE_TASKS;
+import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
+import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
+import static android.app.ActivityManagerInternal.ASSIST_KEY_CONTENT;
+import static android.app.ActivityManagerInternal.ASSIST_KEY_DATA;
+import static android.app.ActivityManagerInternal.ASSIST_KEY_RECEIVER_EXTRAS;
+import static android.app.ActivityManagerInternal.ASSIST_KEY_STRUCTURE;
+import static android.app.ActivityTaskManager.INVALID_STACK_ID;
+import static android.app.ActivityTaskManager.RESIZE_MODE_PRESERVE_WINDOW;
import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
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_SPLIT_SCREEN_SECONDARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+import static android.os.Process.SYSTEM_UID;
+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 android.view.WindowManager.TRANSIT_TASK_IN_PLACE;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.am.ActivityManagerService.ALLOW_FULL_ONLY;
import static com.android.server.am.ActivityManagerService.ANIMATE;
+import static com.android.server.am.ActivityManagerService.DISPATCH_SCREEN_KEYGUARD_MSG;
+import static com.android.server.am.ActivityManagerService.ENTER_ANIMATION_COMPLETE_MSG;
+import static com.android.server.am.ActivityManagerService.STOCK_PM_FLAGS;
+import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
+import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
+import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
+import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
+import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
+import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
+import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
+import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
+import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
+import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
+import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
+import android.Manifest;
+import android.annotation.Nullable;
+import android.annotation.UserIdInt;
+import android.app.Activity;
import android.app.ActivityManager;
+import android.app.ActivityOptions;
+import android.app.ActivityTaskManager;
+import android.app.AppGlobals;
import android.app.IActivityTaskManager;
+import android.app.IApplicationThread;
+import android.app.IAssistDataReceiver;
+import android.app.ITaskStackListener;
+import android.app.PictureInPictureParams;
+import android.app.ProfilerInfo;
+import android.app.RemoteAction;
+import android.app.WaitResult;
import android.app.WindowConfiguration;
+import android.app.admin.DevicePolicyCache;
+import android.app.assist.AssistContent;
+import android.app.assist.AssistStructure;
+import android.app.usage.UsageEvents;
+import android.content.ActivityNotFoundException;
+import android.content.ComponentName;
import android.content.Context;
+import android.content.IIntentSender;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ParceledListSlice;
+import android.content.pm.ResolveInfo;
+import android.content.res.Configuration;
+import android.graphics.Bitmap;
+import android.graphics.Point;
import android.graphics.Rect;
+import android.metrics.LogMaker;
+import android.net.Uri;
import android.os.Binder;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.PersistableBundle;
+import android.os.RemoteException;
+import android.os.TransactionTooLargeException;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.service.voice.IVoiceInteractionSession;
+import android.service.voice.VoiceInteractionManagerInternal;
+import android.telecom.TelecomManager;
+import android.text.TextUtils;
import android.util.Slog;
-import com.android.server.SystemService;
+import android.view.IRecentsAnimationRunner;
+import android.view.RemoteAnimationAdapter;
+import android.view.RemoteAnimationDefinition;
+import com.android.internal.app.AssistUtils;
+import com.android.internal.app.IVoiceInteractor;
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.os.logging.MetricsLoggerWrapper;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.internal.policy.IKeyguardDismissCallback;
+import com.android.internal.policy.KeyguardDismissCallback;
+import com.android.server.LocalServices;
+import com.android.server.SystemService;
+import com.android.server.Watchdog;
+import com.android.server.vr.VrManagerInternal;
+import com.android.server.wm.PinnedStackWindowController;
+
+import java.io.File;
import java.util.ArrayList;
import java.util.List;
@@ -52,6 +161,11 @@
public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityTaskManagerService" : TAG_AM;
private static final String TAG_STACK = TAG + POSTFIX_STACK;
+ private 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 Context mContext;
private ActivityManagerService mAm;
@@ -59,10 +173,54 @@
Object mGlobalLock;
private ActivityStackSupervisor mStackSupervisor;
+ /** 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;
+
+ // How long to wait in getAssistContextExtras for the activity and foreground services
+ // to respond with the result.
+ private static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
+
+ // How long top wait when going through the modern assist (which doesn't need to block
+ // on getting this result before starting to launch its UI).
+ private static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
+
+ // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
+ private static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
+
+ private final ArrayList<PendingAssistExtras> mPendingAssistExtras = new ArrayList<>();
+
+ boolean mSuppressResizeConfigChanges;
+
+ private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
+ new UpdateConfigurationResult();
+
+ static final class UpdateConfigurationResult {
+ // Configuration changes that were updated.
+ int changes;
+ // If the activity was relaunched to match the new configuration.
+ boolean activityRelaunched;
+
+ void reset() {
+ changes = 0;
+ activityRelaunched = false;
+ }
+ }
+
ActivityTaskManagerService(Context context) {
mContext = context;
}
+ void onSystemReady() {
+ mAssistUtils = new AssistUtils(mContext);
+ }
+
// TODO: Will be converted to WM lock once transition is complete.
void setActivityManagerService(ActivityManagerService am) {
mAm = am;
@@ -89,6 +247,1036 @@
}
@Override
+ public final int startActivity(IApplicationThread caller, String callingPackage,
+ Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
+ int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
+ return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
+ resultWho, requestCode, startFlags, profilerInfo, bOptions,
+ UserHandle.getCallingUserId());
+ }
+
+ @Override
+ public final int startActivities(IApplicationThread caller, String callingPackage,
+ Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
+ int userId) {
+ final String reason = "startActivities";
+ mAm.enforceNotIsolatedCaller(reason);
+ userId = mAm.mUserController.handleIncomingUser(Binder.getCallingPid(),
+ Binder.getCallingUid(), userId, false, ALLOW_FULL_ONLY, reason, null);
+ // TODO: Switch to user app stacks here.
+ return mAm.getActivityStartController().startActivities(caller, -1, callingPackage, intents,
+ resolvedTypes, resultTo, SafeActivityOptions.fromBundle(bOptions), userId, reason);
+ }
+
+ @Override
+ public int startActivityAsUser(IApplicationThread caller, String callingPackage,
+ Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
+ int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
+ return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
+ resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
+ true /*validateIncomingUser*/);
+ }
+
+ int startActivityAsUser(IApplicationThread caller, String callingPackage,
+ Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
+ int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
+ boolean validateIncomingUser) {
+ mAm.enforceNotIsolatedCaller("startActivityAsUser");
+
+ userId = mAm.getActivityStartController().checkTargetUser(userId, validateIncomingUser,
+ Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
+
+ // TODO: Switch to user app stacks here.
+ return mAm.getActivityStartController().obtainStarter(intent, "startActivityAsUser")
+ .setCaller(caller)
+ .setCallingPackage(callingPackage)
+ .setResolvedType(resolvedType)
+ .setResultTo(resultTo)
+ .setResultWho(resultWho)
+ .setRequestCode(requestCode)
+ .setStartFlags(startFlags)
+ .setProfilerInfo(profilerInfo)
+ .setActivityOptions(bOptions)
+ .setMayWait(userId)
+ .execute();
+
+ }
+
+ @Override
+ public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
+ IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
+ String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
+ throws TransactionTooLargeException {
+ mAm.enforceNotIsolatedCaller("startActivityIntentSender");
+ // Refuse possible leaked file descriptors
+ if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
+ throw new IllegalArgumentException("File descriptors passed in Intent");
+ }
+
+ if (!(target instanceof PendingIntentRecord)) {
+ throw new IllegalArgumentException("Bad PendingIntent object");
+ }
+
+ PendingIntentRecord pir = (PendingIntentRecord)target;
+
+ synchronized (mGlobalLock) {
+ // If this is coming from the currently resumed activity, it is
+ // effectively saying that app switches are allowed at this point.
+ final ActivityStack stack = mAm.getFocusedStack();
+ if (stack.mResumedActivity != null &&
+ stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
+ mAm.mAppSwitchesAllowedTime = 0;
+ }
+ }
+ int ret = pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
+ resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
+ return ret;
+ }
+
+ @Override
+ public boolean startNextMatchingActivity(IBinder callingActivity, Intent intent,
+ Bundle bOptions) {
+ // Refuse possible leaked file descriptors
+ if (intent != null && intent.hasFileDescriptors()) {
+ throw new IllegalArgumentException("File descriptors passed in Intent");
+ }
+ SafeActivityOptions options = SafeActivityOptions.fromBundle(bOptions);
+
+ synchronized (mGlobalLock) {
+ final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
+ if (r == null) {
+ SafeActivityOptions.abort(options);
+ return false;
+ }
+ if (r.app == null || r.app.thread == null) {
+ // The caller is not running... d'oh!
+ SafeActivityOptions.abort(options);
+ return false;
+ }
+ intent = new Intent(intent);
+ // The caller is not allowed to change the data.
+ intent.setDataAndType(r.intent.getData(), r.intent.getType());
+ // And we are resetting to find the next component...
+ intent.setComponent(null);
+
+ final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
+
+ ActivityInfo aInfo = null;
+ try {
+ List<ResolveInfo> resolves =
+ AppGlobals.getPackageManager().queryIntentActivities(
+ intent, r.resolvedType,
+ PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
+ UserHandle.getCallingUserId()).getList();
+
+ // Look for the original activity in the list...
+ final int N = resolves != null ? resolves.size() : 0;
+ for (int i=0; i<N; i++) {
+ ResolveInfo rInfo = resolves.get(i);
+ if (rInfo.activityInfo.packageName.equals(r.packageName)
+ && rInfo.activityInfo.name.equals(r.info.name)) {
+ // We found the current one... the next matching is
+ // after it.
+ i++;
+ if (i<N) {
+ aInfo = resolves.get(i).activityInfo;
+ }
+ if (debug) {
+ Slog.v(TAG, "Next matching activity: found current " + r.packageName
+ + "/" + r.info.name);
+ Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
+ ? "null" : aInfo.packageName + "/" + aInfo.name));
+ }
+ break;
+ }
+ }
+ } catch (RemoteException e) {
+ }
+
+ if (aInfo == null) {
+ // Nobody who is next!
+ SafeActivityOptions.abort(options);
+ if (debug) Slog.d(TAG, "Next matching activity: nothing found");
+ return false;
+ }
+
+ intent.setComponent(new ComponentName(
+ aInfo.applicationInfo.packageName, aInfo.name));
+ intent.setFlags(intent.getFlags()&~(
+ Intent.FLAG_ACTIVITY_FORWARD_RESULT|
+ Intent.FLAG_ACTIVITY_CLEAR_TOP|
+ Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
+ FLAG_ACTIVITY_NEW_TASK));
+
+ // Okay now we need to start the new activity, replacing the currently running activity.
+ // This is a little tricky because we want to start the new one as if the current one is
+ // finished, but not finish the current one first so that there is no flicker.
+ // And thus...
+ final boolean wasFinishing = r.finishing;
+ r.finishing = true;
+
+ // Propagate reply information over to the new activity.
+ final ActivityRecord resultTo = r.resultTo;
+ final String resultWho = r.resultWho;
+ final int requestCode = r.requestCode;
+ r.resultTo = null;
+ if (resultTo != null) {
+ resultTo.removeResultsLocked(r, resultWho, requestCode);
+ }
+
+ final long origId = Binder.clearCallingIdentity();
+ // TODO(b/64750076): Check if calling pid should really be -1.
+ final int res = mAm.getActivityStartController()
+ .obtainStarter(intent, "startNextMatchingActivity")
+ .setCaller(r.app.thread)
+ .setResolvedType(r.resolvedType)
+ .setActivityInfo(aInfo)
+ .setResultTo(resultTo != null ? resultTo.appToken : null)
+ .setResultWho(resultWho)
+ .setRequestCode(requestCode)
+ .setCallingPid(-1)
+ .setCallingUid(r.launchedFromUid)
+ .setCallingPackage(r.launchedFromPackage)
+ .setRealCallingPid(-1)
+ .setRealCallingUid(r.launchedFromUid)
+ .setActivityOptions(options)
+ .execute();
+ Binder.restoreCallingIdentity(origId);
+
+ r.finishing = wasFinishing;
+ if (res != ActivityManager.START_SUCCESS) {
+ return false;
+ }
+ return true;
+ }
+ }
+
+ @Override
+ public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
+ Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
+ int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
+ final WaitResult res = new WaitResult();
+ synchronized (mGlobalLock) {
+ mAm.enforceNotIsolatedCaller("startActivityAndWait");
+ userId = mAm.mUserController.handleIncomingUser(Binder.getCallingPid(),
+ Binder.getCallingUid(), userId, false, ALLOW_FULL_ONLY,
+ "startActivityAndWait", null);
+ // TODO: Switch to user app stacks here.
+ mAm.getActivityStartController().obtainStarter(intent, "startActivityAndWait")
+ .setCaller(caller)
+ .setCallingPackage(callingPackage)
+ .setResolvedType(resolvedType)
+ .setResultTo(resultTo)
+ .setResultWho(resultWho)
+ .setRequestCode(requestCode)
+ .setStartFlags(startFlags)
+ .setActivityOptions(bOptions)
+ .setMayWait(userId)
+ .setProfilerInfo(profilerInfo)
+ .setWaitResult(res)
+ .execute();
+ }
+ return res;
+ }
+
+ @Override
+ public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
+ Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
+ int startFlags, Configuration config, Bundle bOptions, int userId) {
+ synchronized (mGlobalLock) {
+ mAm.enforceNotIsolatedCaller("startActivityWithConfig");
+ userId = mAm.mUserController.handleIncomingUser(Binder.getCallingPid(),
+ Binder.getCallingUid(), userId, false, ALLOW_FULL_ONLY,
+ "startActivityWithConfig", null);
+ // TODO: Switch to user app stacks here.
+ return mAm.getActivityStartController().obtainStarter(intent, "startActivityWithConfig")
+ .setCaller(caller)
+ .setCallingPackage(callingPackage)
+ .setResolvedType(resolvedType)
+ .setResultTo(resultTo)
+ .setResultWho(resultWho)
+ .setRequestCode(requestCode)
+ .setStartFlags(startFlags)
+ .setGlobalConfiguration(config)
+ .setActivityOptions(bOptions)
+ .setMayWait(userId)
+ .execute();
+ }
+ }
+
+ @Override
+ public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
+ Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
+ int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
+ int userId) {
+
+ // This is very dangerous -- it allows you to perform a start activity (including
+ // permission grants) as any app that may launch one of your own activities. So
+ // we will only allow this to be done from activities that are part of the core framework,
+ // and then only when they are running as the system.
+ final ActivityRecord sourceRecord;
+ final int targetUid;
+ final String targetPackage;
+ final boolean isResolver;
+ synchronized (mGlobalLock) {
+ if (resultTo == null) {
+ throw new SecurityException("Must be called from an activity");
+ }
+ sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
+ if (sourceRecord == null) {
+ throw new SecurityException("Called with bad activity token: " + resultTo);
+ }
+ if (!sourceRecord.info.packageName.equals("android")) {
+ throw new SecurityException(
+ "Must be called from an activity that is declared in the android package");
+ }
+ if (sourceRecord.app == null) {
+ throw new SecurityException("Called without a process attached to activity");
+ }
+ if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) {
+ // This is still okay, as long as this activity is running under the
+ // uid of the original calling activity.
+ if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
+ throw new SecurityException(
+ "Calling activity in uid " + sourceRecord.app.uid
+ + " must be system uid or original calling uid "
+ + sourceRecord.launchedFromUid);
+ }
+ }
+ if (ignoreTargetSecurity) {
+ if (intent.getComponent() == null) {
+ throw new SecurityException(
+ "Component must be specified with ignoreTargetSecurity");
+ }
+ if (intent.getSelector() != null) {
+ throw new SecurityException(
+ "Selector not allowed with ignoreTargetSecurity");
+ }
+ }
+ targetUid = sourceRecord.launchedFromUid;
+ targetPackage = sourceRecord.launchedFromPackage;
+ isResolver = sourceRecord.isResolverOrChildActivity();
+ }
+
+ if (userId == UserHandle.USER_NULL) {
+ userId = UserHandle.getUserId(sourceRecord.app.uid);
+ }
+
+ // TODO: Switch to user app stacks here.
+ try {
+ return mAm.getActivityStartController().obtainStarter(intent, "startActivityAsCaller")
+ .setCallingUid(targetUid)
+ .setCallingPackage(targetPackage)
+ .setResolvedType(resolvedType)
+ .setResultTo(resultTo)
+ .setResultWho(resultWho)
+ .setRequestCode(requestCode)
+ .setStartFlags(startFlags)
+ .setActivityOptions(bOptions)
+ .setMayWait(userId)
+ .setIgnoreTargetSecurity(ignoreTargetSecurity)
+ .setFilterCallingUid(isResolver ? 0 /* system */ : targetUid)
+ .execute();
+ } catch (SecurityException e) {
+ // XXX need to figure out how to propagate to original app.
+ // A SecurityException here is generally actually a fault of the original
+ // calling activity (such as a fairly granting permissions), so propagate it
+ // back to them.
+ /*
+ StringBuilder msg = new StringBuilder();
+ msg.append("While launching");
+ msg.append(intent.toString());
+ msg.append(": ");
+ msg.append(e.getMessage());
+ */
+ throw e;
+ }
+ }
+
+ @Override
+ public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
+ Intent intent, String resolvedType, IVoiceInteractionSession session,
+ IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
+ Bundle bOptions, int userId) {
+ mAm.enforceCallingPermission(BIND_VOICE_INTERACTION, "startVoiceActivity()");
+ if (session == null || interactor == null) {
+ throw new NullPointerException("null session or interactor");
+ }
+ userId = mAm.mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
+ ALLOW_FULL_ONLY, "startVoiceActivity", null);
+ // TODO: Switch to user app stacks here.
+ return mAm.getActivityStartController().obtainStarter(intent, "startVoiceActivity")
+ .setCallingUid(callingUid)
+ .setCallingPackage(callingPackage)
+ .setResolvedType(resolvedType)
+ .setVoiceSession(session)
+ .setVoiceInteractor(interactor)
+ .setStartFlags(startFlags)
+ .setProfilerInfo(profilerInfo)
+ .setActivityOptions(bOptions)
+ .setMayWait(userId)
+ .execute();
+ }
+
+ @Override
+ public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
+ Intent intent, String resolvedType, Bundle bOptions, int userId) {
+ mAm.enforceCallingPermission(BIND_VOICE_INTERACTION, "startAssistantActivity()");
+ userId = mAm.mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
+ ALLOW_FULL_ONLY, "startAssistantActivity", null);
+
+ return mAm.getActivityStartController().obtainStarter(intent, "startAssistantActivity")
+ .setCallingUid(callingUid)
+ .setCallingPackage(callingPackage)
+ .setResolvedType(resolvedType)
+ .setActivityOptions(bOptions)
+ .setMayWait(userId)
+ .execute();
+ }
+
+ @Override
+ public void startRecentsActivity(Intent intent, IAssistDataReceiver assistDataReceiver,
+ IRecentsAnimationRunner recentsAnimationRunner) {
+ mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "startRecentsActivity()");
+ final int callingPid = Binder.getCallingPid();
+ final long origId = Binder.clearCallingIdentity();
+ try {
+ synchronized (mGlobalLock) {
+ final ComponentName recentsComponent = mAm.getRecentTasks().getRecentsComponent();
+ final int recentsUid = mAm.getRecentTasks().getRecentsComponentUid();
+
+ // Start a new recents animation
+ final RecentsAnimation anim = new RecentsAnimation(mAm, mStackSupervisor,
+ mAm.getActivityStartController(), mAm.mWindowManager, mAm.mUserController,
+ callingPid);
+ anim.startRecentsActivity(intent, recentsAnimationRunner, recentsComponent,
+ recentsUid, assistDataReceiver);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(origId);
+ }
+ }
+
+ @Override
+ public final int startActivityFromRecents(int taskId, Bundle bOptions) {
+ mAm.enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS,
+ "startActivityFromRecents()");
+
+ final int callingPid = Binder.getCallingPid();
+ final int callingUid = Binder.getCallingUid();
+ final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(bOptions);
+ final long origId = Binder.clearCallingIdentity();
+ try {
+ synchronized (mGlobalLock) {
+ return mStackSupervisor.startActivityFromRecents(callingPid, callingUid, taskId,
+ safeOptions);
+ }
+ } 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 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");
+ }
+
+ synchronized (mGlobalLock) {
+ ActivityRecord r = ActivityRecord.isInStackLocked(token);
+ if (r == null) {
+ return true;
+ }
+ // Keep track of the root activity of the task before we finish it
+ TaskRecord tr = r.getTask();
+ 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 (mAm.getLockTaskController().activityBlockedFromFinish(r)) {
+ return false;
+ }
+
+ if (mAm.mController != null) {
+ // Find the first activity that is not finishing.
+ ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
+ if (next != null) {
+ // ask watcher if this is allowed
+ boolean resumeOK = true;
+ try {
+ resumeOK = mAm.mController.activityResuming(next.packageName);
+ } catch (RemoteException e) {
+ mAm.mController = null;
+ Watchdog.getInstance().setActivityController(null);
+ }
+
+ if (!resumeOK) {
+ Slog.i(TAG, "Not finishing activity because controller resumed");
+ return false;
+ }
+ }
+ }
+ final long origId = Binder.clearCallingIdentity();
+ 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.
+ res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
+ finishWithRootActivity, "finish-activity");
+ if (!res) {
+ Slog.i(TAG, "Removing task failed to finish activity");
+ }
+ } else {
+ res = tr.getStack().requestFinishActivityLocked(token, resultCode,
+ resultData, "app-request", true);
+ if (!res) {
+ Slog.i(TAG, "Failed to finish by app-request");
+ }
+ }
+ return res;
+ } finally {
+ 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.
+ final TaskRecord task = r.getTask();
+ if (mAm.getLockTaskController().activityBlockedFromFinish(r)) {
+ return false;
+ }
+ return task.getStack().finishActivityAffinityLocked(r);
+ } finally {
+ Binder.restoreCallingIdentity(origId);
+ }
+ }
+ }
+
+ @Override
+ public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
+ final long origId = Binder.clearCallingIdentity();
+ synchronized (mGlobalLock) {
+ ActivityStack stack = ActivityRecord.getStackLocked(token);
+ if (stack != null) {
+ ActivityRecord r =
+ mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
+ false /* processPausingActivities */, config);
+ if (stopProfiling) {
+ if ((mAm.mProfileProc == r.app) && mAm.mProfilerInfo != null) {
+ mAm.clearProfilerLocked();
+ }
+ }
+ }
+ }
+ Binder.restoreCallingIdentity(origId);
+ }
+
+ @Override
+ public final void activityResumed(IBinder token) {
+ final long origId = Binder.clearCallingIdentity();
+ synchronized (mGlobalLock) {
+ ActivityRecord.activityResumedLocked(token);
+ mAm.mWindowManager.notifyAppResumedFinished(token);
+ }
+ Binder.restoreCallingIdentity(origId);
+ }
+
+ @Override
+ public final void activityPaused(IBinder token) {
+ final long origId = Binder.clearCallingIdentity();
+ synchronized (mGlobalLock) {
+ ActivityStack stack = ActivityRecord.getStackLocked(token);
+ if (stack != null) {
+ stack.activityPausedLocked(token, false);
+ }
+ }
+ 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();
+
+ synchronized (mGlobalLock) {
+ final ActivityRecord r = ActivityRecord.isInStackLocked(token);
+ if (r != null) {
+ r.activityStoppedLocked(icicle, persistentState, description);
+ }
+ }
+
+ mAm.trimApplications();
+
+ Binder.restoreCallingIdentity(origId);
+ }
+
+ @Override
+ public final void activityDestroyed(IBinder token) {
+ if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
+ synchronized (mGlobalLock) {
+ ActivityStack stack = ActivityRecord.getStackLocked(token);
+ if (stack != null) {
+ stack.activityDestroyedLocked(token, "activityDestroyed");
+ }
+ }
+ }
+
+ @Override
+ public final void activityRelaunched(IBinder token) {
+ final long origId = Binder.clearCallingIdentity();
+ synchronized (mGlobalLock) {
+ mStackSupervisor.activityRelaunchedLocked(token);
+ }
+ Binder.restoreCallingIdentity(origId);
+ }
+
+ public final void activitySlept(IBinder token) {
+ if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
+
+ final long origId = Binder.clearCallingIdentity();
+
+ synchronized (mGlobalLock) {
+ final ActivityRecord r = ActivityRecord.isInStackLocked(token);
+ if (r != null) {
+ mStackSupervisor.activitySleptLocked(r);
+ }
+ }
+
+ 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) {
+ ActivityRecord r = ActivityRecord.isInStackLocked(token);
+ if (r == null) {
+ return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+ }
+ return r.getRequestedOrientation();
+ }
+ }
+
+ @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 == mStackSupervisor.getResumedActivityLocked()) {
+ if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
+ mAm.applyUpdateLockStateLocked(r);
+ }
+ }
+ }
+
+ @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() {
+ mAm.enforceNotIsolatedCaller("isTopActivityImmersive");
+ synchronized (mGlobalLock) {
+ final ActivityRecord r = mAm.getFocusedStack().topRunningActivityLocked();
+ return (r != null) ? r.immersive : false;
+ }
+ }
+
+ @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(
+ ActivityStack.ActivityState.RESUMED, ActivityStack.ActivityState.PAUSING)) {
+ mAm.mWindowManager.overridePendingAppTransition(packageName,
+ enterAnim, exitAnim, null);
+ }
+
+ Binder.restoreCallingIdentity(origId);
+ }
+ }
+
+ @Override
+ public int getFrontActivityScreenCompatMode() {
+ mAm.enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
+ synchronized (mGlobalLock) {
+ return mAm.mCompatModePackages.getFrontActivityScreenCompatModeLocked();
+ }
+ }
+
+ @Override
+ public void setFrontActivityScreenCompatMode(int mode) {
+ mAm.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
+ "setFrontActivityScreenCompatMode");
+ synchronized (mGlobalLock) {
+ mAm.mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
+ }
+ }
+
+ @Override
+ public int getLaunchedFromUid(IBinder activityToken) {
+ ActivityRecord srec;
+ synchronized (mGlobalLock) {
+ srec = ActivityRecord.forTokenLocked(activityToken);
+ }
+ if (srec == null) {
+ return -1;
+ }
+ return srec.launchedFromUid;
+ }
+
+ @Override
+ public String getLaunchedFromPackage(IBinder activityToken) {
+ ActivityRecord srec;
+ synchronized (mGlobalLock) {
+ srec = ActivityRecord.forTokenLocked(activityToken);
+ }
+ if (srec == null) {
+ return null;
+ }
+ return srec.launchedFromPackage;
+ }
+
+ @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;
+ }
+ final boolean translucentChanged = r.changeWindowTranslucency(true);
+ if (translucentChanged) {
+ mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
+ }
+ mAm.mWindowManager.setAppFullscreen(token, true);
+ return translucentChanged;
+ }
+ } 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 TaskRecord task = r.getTask();
+ int index = task.mActivities.lastIndexOf(r);
+ if (index > 0) {
+ ActivityRecord under = task.mActivities.get(index - 1);
+ under.returningOptions = safeOptions != null ? safeOptions.getOptions(r) : null;
+ }
+ final boolean translucentChanged = r.changeWindowTranslucency(false);
+ if (translucentChanged) {
+ r.getStack().convertActivityToTranslucent(r);
+ }
+ mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
+ mAm.mWindowManager.setAppFullscreen(token, false);
+ return translucentChanged;
+ }
+ } finally {
+ Binder.restoreCallingIdentity(origId);
+ }
+ }
+
+ @Override
+ public void notifyActivityDrawn(IBinder token) {
+ if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
+ synchronized (mGlobalLock) {
+ ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
+ if (r != null) {
+ r.getStack().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 getActivityDisplayId(IBinder activityToken) throws RemoteException {
+ synchronized (mGlobalLock) {
+ final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
+ if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
+ return stack.mDisplayId;
+ }
+ return DEFAULT_DISPLAY;
+ }
+ }
+
+ @Override
+ public ActivityManager.StackInfo getFocusedStackInfo() throws RemoteException {
+ mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
+ long ident = Binder.clearCallingIdentity();
+ try {
+ synchronized (mGlobalLock) {
+ ActivityStack focusedStack = mAm.getFocusedStack();
+ if (focusedStack != null) {
+ return mStackSupervisor.getStackInfo(focusedStack.mStackId);
+ }
+ return null;
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ @Override
+ public void setFocusedStack(int stackId) {
+ mAm.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
+ if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
+ final long callingId = Binder.clearCallingIdentity();
+ try {
+ synchronized (mGlobalLock) {
+ final ActivityStack stack = mStackSupervisor.getStack(stackId);
+ if (stack == null) {
+ Slog.w(TAG, "setFocusedStack: No stack with id=" + stackId);
+ return;
+ }
+ final ActivityRecord r = stack.topRunningActivityLocked();
+ if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
+ r, "setFocusedStack")) {
+ mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ }
+ }
+ } finally {
+ Binder.restoreCallingIdentity(callingId);
+ }
+ }
+
+ @Override
+ public void setFocusedTask(int taskId) {
+ mAm.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
+ if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
+ final long callingId = Binder.clearCallingIdentity();
+ try {
+ synchronized (mGlobalLock) {
+ final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
+ if (task == null) {
+ return;
+ }
+ final ActivityRecord r = task.topRunningActivityLocked();
+ if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
+ mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ }
+ }
+ } finally {
+ Binder.restoreCallingIdentity(callingId);
+ }
+ }
+
+ @Override
+ public boolean removeTask(int taskId) {
+ mAm.enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeTask()");
+ synchronized (mGlobalLock) {
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS,
+ "remove-task");
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+ }
+
+ @Override
+ public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
+ synchronized (mGlobalLock) {
+ final ActivityRecord srec = ActivityRecord.forTokenLocked(token);
+ if (srec != null) {
+ return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
+ Intent resultData) {
+
+ synchronized (mGlobalLock) {
+ final ActivityRecord r = ActivityRecord.forTokenLocked(token);
+ if (r != null) {
+ return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * 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) {
+ mAm.enforceNotIsolatedCaller("moveActivityTaskToBack");
+ synchronized (mGlobalLock) {
+ final long origId = Binder.clearCallingIdentity();
+ try {
+ int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
+ final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
+ if (task != null) {
+ return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(origId);
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public Rect getTaskBounds(int taskId) {
+ mAm.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
+ long ident = Binder.clearCallingIdentity();
+ Rect rect = new Rect();
+ try {
+ synchronized (mGlobalLock) {
+ final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
+ MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
+ if (task == null) {
+ Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
+ return rect;
+ }
+ if (task.getStack() != null) {
+ // Return the bounds from window manager since it will be adjusted for various
+ // things like the presense of a docked stack for tasks that aren't resizeable.
+ task.getWindowContainerBounds(rect);
+ } else {
+ // Task isn't in window manager yet since it isn't associated with a stack.
+ // Return the persist value from activity manager
+ if (!task.matchParentBounds()) {
+ rect.set(task.getBounds());
+ } else if (task.mLastNonFullscreenBounds != null) {
+ rect.set(task.mLastNonFullscreenBounds);
+ }
+ }
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ return rect;
+ }
+
+ @Override
+ public ActivityManager.TaskDescription getTaskDescription(int id) {
+ synchronized (mGlobalLock) {
+ mAm.enforceCallerIsRecentsOrHasPermission(
+ MANAGE_ACTIVITY_STACKS, "getTaskDescription()");
+ final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
+ MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
+ if (tr != null) {
+ return tr.lastTaskDescription;
+ }
+ }
+ return null;
+ }
+
+ @Override
public void setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) {
if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
setTaskWindowingModeSplitScreenPrimary(taskId, SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT,
@@ -126,6 +1314,104 @@
}
@Override
+ public String getCallingPackage(IBinder token) {
+ synchronized (this) {
+ ActivityRecord r = getCallingRecordLocked(token);
+ return r != null ? r.info.packageName : null;
+ }
+ }
+
+ @Override
+ public ComponentName getCallingActivity(IBinder token) {
+ synchronized (this) {
+ 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;
+ }
+
+ @Override
+ public void unhandledBack() {
+ mAm.enforceCallingPermission(android.Manifest.permission.FORCE_BACK, "unhandledBack()");
+
+ synchronized (mGlobalLock) {
+ final long origId = Binder.clearCallingIdentity();
+ try {
+ mAm.getFocusedStack().unhandledBackLocked();
+ } finally {
+ Binder.restoreCallingIdentity(origId);
+ }
+ }
+ }
+
+ /**
+ * TODO: Add mController hook
+ */
+ @Override
+ public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
+ mAm.enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
+
+ if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
+ synchronized (mGlobalLock) {
+ moveTaskToFrontLocked(taskId, flags, SafeActivityOptions.fromBundle(bOptions),
+ false /* fromRecents */);
+ }
+ }
+
+ void moveTaskToFrontLocked(int taskId, int flags, SafeActivityOptions options,
+ boolean fromRecents) {
+
+ if (!mAm.checkAppSwitchAllowedLocked(Binder.getCallingPid(),
+ Binder.getCallingUid(), -1, -1, "Task to front")) {
+ SafeActivityOptions.abort(options);
+ return;
+ }
+ final long origId = Binder.clearCallingIdentity();
+ try {
+ final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
+ if (task == null) {
+ Slog.d(TAG, "Could not find task for id: "+ taskId);
+ return;
+ }
+ if (mAm.getLockTaskController().isLockTaskModeViolation(task)) {
+ Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
+ return;
+ }
+ ActivityOptions realOptions = options != null
+ ? options.getOptions(mStackSupervisor)
+ : null;
+ mStackSupervisor.findTaskToMoveToFront(task, flags, realOptions, "moveTaskToFront",
+ false /* forceNonResizable */);
+
+ final ActivityRecord topActivity = task.getTopActivity();
+ if (topActivity != null) {
+
+ // We are reshowing a task, use a starting window to hide the initial draw delay
+ // so the transition can start earlier.
+ topActivity.showStartingWindow(null /* prev */, false /* newTask */,
+ true /* taskSwitch */, fromRecents);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(origId);
+ }
+ SafeActivityOptions.abort(options);
+ }
+
+ @Override
+ public int getTaskForActivity(IBinder token, boolean onlyRoot) {
+ synchronized (mGlobalLock) {
+ return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
+ }
+ }
+
+ @Override
public List<ActivityManager.RunningTaskInfo> getTasks(int maxNum) {
return getFilteredTasks(maxNum, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED);
}
@@ -150,6 +1436,29 @@
}
@Override
+ public final void finishSubActivity(IBinder token, String resultWho, int requestCode) {
+ synchronized (mGlobalLock) {
+ final long origId = Binder.clearCallingIdentity();
+ ActivityRecord r = ActivityRecord.isInStackLocked(token);
+ if (r != null) {
+ r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
+ }
+ Binder.restoreCallingIdentity(origId);
+ }
+ }
+
+ @Override
+ public boolean willActivityBeVisible(IBinder token) {
+ synchronized(this) {
+ ActivityStack stack = ActivityRecord.getStackLocked(token);
+ if (stack != null) {
+ return stack.willActivityBeVisibleLocked(token);
+ }
+ return false;
+ }
+ }
+
+ @Override
public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
synchronized (mGlobalLock) {
@@ -306,4 +1615,1716 @@
}
}
}
+
+ @Override
+ public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
+ int userId) {
+ final int callingUid = Binder.getCallingUid();
+ userId = mAm.mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
+ false, ALLOW_FULL_ONLY, "getRecentTasks", null);
+ final boolean allowed = mAm.isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
+ callingUid);
+ final boolean detailed = mAm.checkCallingPermission(
+ android.Manifest.permission.GET_DETAILED_TASKS)
+ == PackageManager.PERMISSION_GRANTED;
+
+ synchronized (mGlobalLock) {
+ return mAm.getRecentTasks().getRecentTasks(maxNum, flags, allowed, detailed, userId,
+ callingUid);
+ }
+ }
+
+ @Override
+ public List<ActivityManager.StackInfo> getAllStackInfos() {
+ mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
+ long ident = Binder.clearCallingIdentity();
+ try {
+ synchronized (mGlobalLock) {
+ return mStackSupervisor.getAllStackInfosLocked();
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ @Override
+ public ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType) {
+ mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
+ long ident = Binder.clearCallingIdentity();
+ try {
+ synchronized (mGlobalLock) {
+ return mStackSupervisor.getStackInfo(windowingMode, activityType);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ @Override
+ public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
+ mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()");
+ final long callingUid = Binder.getCallingUid();
+ final long origId = Binder.clearCallingIdentity();
+ try {
+ synchronized (mGlobalLock) {
+ // Cancel the recents animation synchronously (do not hold the WM lock)
+ mAm.mWindowManager.cancelRecentsAnimationSynchronously(restoreHomeStackPosition
+ ? REORDER_MOVE_TO_ORIGINAL_POSITION
+ : REORDER_KEEP_IN_PLACE, "cancelRecentsAnimation/uid=" + callingUid);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(origId);
+ }
+ }
+
+ @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) throws RemoteException {
+ mAm.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
+ // This makes inner call to look as if it was initiated by system.
+ long ident = Binder.clearCallingIdentity();
+ try {
+ synchronized (mGlobalLock) {
+ final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
+
+ // When starting lock task mode the stack must be in front and focused
+ task.getStack().moveToFront("startSystemLockTaskMode");
+ startLockTaskModeLocked(task, true /* isSystemCaller */);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ @Override
+ public void stopLockTaskModeByToken(IBinder token) {
+ synchronized (mGlobalLock) {
+ final ActivityRecord r = ActivityRecord.forTokenLocked(token);
+ if (r == null) {
+ return;
+ }
+ stopLockTaskModeInternal(r.getTask(), 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.
+ */
+ @Override
+ public void stopSystemLockTaskMode() throws RemoteException {
+ mAm.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode");
+ stopLockTaskModeInternal(null, true /* isSystemCaller */);
+ }
+
+ private void startLockTaskModeLocked(@Nullable TaskRecord task, boolean isSystemCaller) {
+ if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
+ if (task == null || task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
+ return;
+ }
+
+ final ActivityStack stack = mStackSupervisor.getFocusedStack();
+ if (stack == null || task != stack.topTask()) {
+ throw new IllegalArgumentException("Invalid task, not in foreground");
+ }
+
+ // {@code isSystemCaller} is used to distinguish whether this request is initiated by the
+ // system or a specific app.
+ // * System-initiated requests will only start the pinned mode (screen pinning)
+ // * App-initiated requests
+ // - will put the device in fully locked mode (LockTask), if the app is whitelisted
+ // - will start the pinned mode, otherwise
+ final int callingUid = Binder.getCallingUid();
+ long ident = Binder.clearCallingIdentity();
+ try {
+ // When a task is locked, dismiss the pinned stack if it exists
+ mStackSupervisor.removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
+
+ mAm.getLockTaskController().startLockTaskMode(task, isSystemCaller, callingUid);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ private void stopLockTaskModeInternal(@Nullable TaskRecord task, boolean isSystemCaller) {
+ final int callingUid = Binder.getCallingUid();
+ long ident = Binder.clearCallingIdentity();
+ try {
+ synchronized (mGlobalLock) {
+ mAm.getLockTaskController().stopLockTaskMode(task, isSystemCaller, callingUid);
+ }
+ // Launch in-call UI if a call is ongoing. This is necessary to allow stopping the lock
+ // task and jumping straight into a call in the case of emergency call back.
+ TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
+ if (tm != null) {
+ tm.showInCallScreen(false);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ @Override
+ public boolean isInLockTaskMode() {
+ return getLockTaskModeState() != LOCK_TASK_MODE_NONE;
+ }
+
+ @Override
+ public int getLockTaskModeState() {
+ synchronized (mGlobalLock) {
+ return mAm.getLockTaskController().getLockTaskModeState();
+ }
+ }
+
+ @Override
+ public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
+ synchronized (mGlobalLock) {
+ ActivityRecord r = ActivityRecord.isInStackLocked(token);
+ if (r != null) {
+ r.setTaskDescription(td);
+ final TaskRecord task = r.getTask();
+ task.updateTaskDescription();
+ mAm.mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, 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();
+ return activityOptions == null ? null : activityOptions.toBundle();
+ }
+ return null;
+ }
+ } finally {
+ Binder.restoreCallingIdentity(origId);
+ }
+ }
+
+ @Override
+ public List<IBinder> getAppTasks(String callingPackage) {
+ int callingUid = Binder.getCallingUid();
+ long ident = Binder.clearCallingIdentity();
+ try {
+ synchronized (mGlobalLock) {
+ return mAm.getRecentTasks().getAppTasksList(callingUid, callingPackage);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ @Override
+ public void finishVoiceTask(IVoiceInteractionSession session) {
+ synchronized (mGlobalLock) {
+ final long origId = Binder.clearCallingIdentity();
+ try {
+ // TODO: VI Consider treating local voice interactions and voice tasks
+ // differently here
+ mStackSupervisor.finishVoiceTask(session);
+ } finally {
+ Binder.restoreCallingIdentity(origId);
+ }
+ }
+
+ }
+
+ @Override
+ public boolean isTopOfTask(IBinder token) {
+ synchronized (mGlobalLock) {
+ ActivityRecord r = ActivityRecord.isInStackLocked(token);
+ if (r == null) {
+ throw new IllegalArgumentException();
+ }
+ return r.getTask().getTopActivity() == r;
+ }
+ }
+
+ @Override
+ public void notifyLaunchTaskBehindComplete(IBinder token) {
+ mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
+ }
+
+ @Override
+ public void notifyEnterAnimationComplete(IBinder token) {
+ mAm.mHandler.sendMessage(mAm.mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
+ }
+
+ /** 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;
+ synchronized (pae) {
+ pae.result = extras;
+ pae.structure = structure;
+ pae.content = content;
+ if (referrer != null) {
+ pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
+ }
+ if (structure != null) {
+ structure.setHomeActivity(pae.isHome);
+ }
+ pae.haveResult = true;
+ pae.notifyAll();
+ if (pae.intent == null && pae.receiver == null) {
+ // Caller is just waiting for the result.
+ return;
+ }
+ }
+ // We are now ready to launch the assist activity.
+ IAssistDataReceiver sendReceiver = null;
+ Bundle sendBundle = null;
+ synchronized (mGlobalLock) {
+ buildAssistBundleLocked(pae, extras);
+ boolean exists = mPendingAssistExtras.remove(pae);
+ mAm.mUiHandler.removeCallbacks(pae);
+ if (!exists) {
+ // Timed out.
+ return;
+ }
+
+ if ((sendReceiver=pae.receiver) != null) {
+ // Caller wants result sent back to them.
+ sendBundle = new Bundle();
+ sendBundle.putBundle(ASSIST_KEY_DATA, pae.extras);
+ sendBundle.putParcelable(ASSIST_KEY_STRUCTURE, pae.structure);
+ sendBundle.putParcelable(ASSIST_KEY_CONTENT, pae.content);
+ sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
+ }
+ }
+ if (sendReceiver != null) {
+ try {
+ sendReceiver.onHandleAssistData(sendBundle);
+ } catch (RemoteException e) {
+ }
+ return;
+ }
+
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ if (TextUtils.equals(pae.intent.getAction(),
+ android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
+ pae.intent.putExtras(pae.extras);
+ mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
+ } else {
+ pae.intent.replaceExtras(pae.extras);
+ pae.intent.setFlags(FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_SINGLE_TOP
+ | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ mAm.closeSystemDialogs("assist");
+
+ try {
+ mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
+ } catch (ActivityNotFoundException e) {
+ Slog.w(TAG, "No activity to handle assist action.", e);
+ }
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ @Override
+ public int addAppTask(IBinder activityToken, Intent intent,
+ ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
+ final int callingUid = Binder.getCallingUid();
+ final long callingIdent = Binder.clearCallingIdentity();
+
+ try {
+ synchronized (mGlobalLock) {
+ ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
+ if (r == null) {
+ throw new IllegalArgumentException("Activity does not exist; token="
+ + activityToken);
+ }
+ ComponentName comp = intent.getComponent();
+ if (comp == null) {
+ throw new IllegalArgumentException("Intent " + intent
+ + " must specify explicit component");
+ }
+ if (thumbnail.getWidth() != mAm.mThumbnailWidth
+ || thumbnail.getHeight() != mAm.mThumbnailHeight) {
+ throw new IllegalArgumentException("Bad thumbnail size: got "
+ + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
+ + mAm.mThumbnailWidth + "x" + mAm.mThumbnailHeight);
+ }
+ if (intent.getSelector() != null) {
+ intent.setSelector(null);
+ }
+ if (intent.getSourceBounds() != null) {
+ intent.setSourceBounds(null);
+ }
+ if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
+ if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
+ // The caller has added this as an auto-remove task... that makes no
+ // sense, so turn off auto-remove.
+ intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
+ }
+ }
+ final ActivityInfo ainfo = AppGlobals.getPackageManager().getActivityInfo(comp,
+ STOCK_PM_FLAGS, UserHandle.getUserId(callingUid));
+ if (ainfo.applicationInfo.uid != callingUid) {
+ throw new SecurityException(
+ "Can't add task for another application: target uid="
+ + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
+ }
+
+ final ActivityStack stack = r.getStack();
+ final TaskRecord task = stack.createTaskRecord(
+ mStackSupervisor.getNextTaskIdForUserLocked(r.userId), ainfo, intent,
+ null /* voiceSession */, null /* voiceInteractor */, !ON_TOP);
+ if (!mAm.getRecentTasks().addToBottom(task)) {
+ // The app has too many tasks already and we can't add any more
+ stack.removeTask(task, "addAppTask", REMOVE_TASK_MODE_DESTROYING);
+ return INVALID_TASK_ID;
+ }
+ task.lastTaskDescription.copyFrom(description);
+
+ // TODO: Send the thumbnail to WM to store it.
+
+ return task.taskId;
+ }
+ } finally {
+ Binder.restoreCallingIdentity(callingIdent);
+ }
+ }
+
+ @Override
+ public Point getAppTaskThumbnailSize() {
+ synchronized (mGlobalLock) {
+ return new Point(mAm.mThumbnailWidth, mAm.mThumbnailHeight);
+ }
+ }
+
+ @Override
+ public void setTaskResizeable(int taskId, int resizeableMode) {
+ synchronized (mGlobalLock) {
+ final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
+ taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
+ if (task == null) {
+ Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
+ return;
+ }
+ task.setResizeMode(resizeableMode);
+ }
+ }
+
+ @Override
+ public void resizeTask(int taskId, Rect bounds, int resizeMode) {
+ mAm.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
+ long ident = Binder.clearCallingIdentity();
+ try {
+ synchronized (mGlobalLock) {
+ TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
+ if (task == null) {
+ Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
+ return;
+ }
+ // Place the task in the right stack if it isn't there already based on
+ // the requested bounds.
+ // The stack transition logic is:
+ // - a null bounds on a freeform task moves that task to fullscreen
+ // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
+ // that task to freeform
+ // - otherwise the task is not moved
+ ActivityStack stack = task.getStack();
+ if (!task.getWindowConfiguration().canResizeTask()) {
+ throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
+ }
+ if (bounds == null && stack.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
+ stack = stack.getDisplay().getOrCreateStack(
+ WINDOWING_MODE_FULLSCREEN, stack.getActivityType(), ON_TOP);
+ } else if (bounds != null && stack.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
+ stack = stack.getDisplay().getOrCreateStack(
+ WINDOWING_MODE_FREEFORM, stack.getActivityType(), ON_TOP);
+ }
+
+ // Reparent the task to the right stack if necessary
+ boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
+ if (stack != task.getStack()) {
+ // Defer resume until the task is resized below
+ task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
+ DEFER_RESUME, "resizeTask");
+ preserveWindow = false;
+ }
+
+ // After reparenting (which only resizes the task to the stack bounds), resize the
+ // task to the actual bounds provided
+ task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ @Override
+ public boolean releaseActivityInstance(IBinder token) {
+ synchronized (mGlobalLock) {
+ final long origId = Binder.clearCallingIdentity();
+ try {
+ ActivityRecord r = ActivityRecord.isInStackLocked(token);
+ if (r == null) {
+ return false;
+ }
+ return r.getStack().safelyDestroyActivityLocked(r, "app-req");
+ } finally {
+ Binder.restoreCallingIdentity(origId);
+ }
+ }
+ }
+
+ @Override
+ public void releaseSomeActivities(IApplicationThread appInt) {
+ synchronized (mGlobalLock) {
+ final long origId = Binder.clearCallingIdentity();
+ try {
+ ProcessRecord app = mAm.getRecordForAppLocked(appInt);
+ mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
+ } finally {
+ Binder.restoreCallingIdentity(origId);
+ }
+ }
+ }
+
+ @Override
+ public void setLockScreenShown(boolean keyguardShowing, boolean aodShowing,
+ int secondaryDisplayShowing) {
+ if (mAm.checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires permission "
+ + android.Manifest.permission.DEVICE_POWER);
+ }
+
+ synchronized (mGlobalLock) {
+ long ident = Binder.clearCallingIdentity();
+ if (mKeyguardShown != keyguardShowing) {
+ mKeyguardShown = keyguardShowing;
+ reportCurKeyguardUsageEventLocked(keyguardShowing);
+ }
+ try {
+ mAm.mKeyguardController.setKeyguardShown(keyguardShowing, aodShowing,
+ secondaryDisplayShowing);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ mAm.mHandler.obtainMessage(DISPATCH_SCREEN_KEYGUARD_MSG, keyguardShowing ? 1 : 0, 0)
+ .sendToTarget();
+ }
+
+ @Override
+ public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
+ userId = mAm.mUserController.handleIncomingUser(Binder.getCallingPid(),
+ Binder.getCallingUid(), userId, false, ALLOW_FULL_ONLY, "getTaskDescriptionIcon", null);
+
+ final File passedIconFile = new File(filePath);
+ final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
+ passedIconFile.getName());
+ if (!legitIconFile.getPath().equals(filePath)
+ || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
+ throw new IllegalArgumentException("Bad file path: " + filePath
+ + " passed for userId " + userId);
+ }
+ return mAm.getRecentTasks().getTaskDescriptionIcon(filePath);
+ }
+
+ @Override
+ public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
+ throws RemoteException {
+ final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(opts);
+ final ActivityOptions activityOptions = safeOptions != null
+ ? safeOptions.getOptions(mStackSupervisor)
+ : null;
+ if (activityOptions == null
+ || activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE
+ || activityOptions.getCustomInPlaceResId() == 0) {
+ throw new IllegalArgumentException("Expected in-place ActivityOption " +
+ "with valid animation");
+ }
+ mAm.mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
+ mAm.mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
+ activityOptions.getCustomInPlaceResId());
+ mAm.mWindowManager.executeAppTransition();
+ }
+
+ @Override
+ public void removeStack(int stackId) {
+ mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()");
+ synchronized (mGlobalLock) {
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ final ActivityStack stack = mStackSupervisor.getStack(stackId);
+ if (stack == null) {
+ Slog.w(TAG, "removeStack: No stack with id=" + stackId);
+ return;
+ }
+ if (!stack.isActivityTypeStandardOrUndefined()) {
+ throw new IllegalArgumentException(
+ "Removing non-standard stack is not allowed.");
+ }
+ mStackSupervisor.removeStack(stack);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+ }
+
+ @Override
+ public void moveStackToDisplay(int stackId, int displayId) {
+ mAm.enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
+
+ synchronized (mGlobalLock) {
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
+ + " to displayId=" + displayId);
+ mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+ }
+
+ @Override
+ public int createStackOnDisplay(int displayId) {
+ mAm.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
+ synchronized (mGlobalLock) {
+ final ActivityDisplay display =
+ mStackSupervisor.getActivityDisplayOrCreateLocked(displayId);
+ if (display == null) {
+ return INVALID_STACK_ID;
+ }
+ // TODO(multi-display): Have the caller pass in the windowing mode and activity type.
+ final ActivityStack stack = display.createStack(
+ WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD,
+ ON_TOP);
+ return (stack != null) ? stack.mStackId : INVALID_STACK_ID;
+ }
+ }
+
+ @Override
+ public void exitFreeformMode(IBinder token) {
+ synchronized (mGlobalLock) {
+ long ident = Binder.clearCallingIdentity();
+ try {
+ final ActivityRecord r = ActivityRecord.forTokenLocked(token);
+ if (r == null) {
+ throw new IllegalArgumentException(
+ "exitFreeformMode: No activity record matching token=" + token);
+ }
+
+ final ActivityStack stack = r.getStack();
+ if (stack == null || !stack.inFreeformWindowingMode()) {
+ throw new IllegalStateException(
+ "exitFreeformMode: You can only go fullscreen from freeform.");
+ }
+
+ stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+ }
+
+ /** Sets the task stack listener that gets callbacks when a task stack changes. */
+ @Override
+ public void registerTaskStackListener(ITaskStackListener listener) {
+ mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
+ "registerTaskStackListener()");
+ mAm.mTaskChangeNotificationController.registerTaskStackListener(listener);
+ }
+
+ /** Unregister a task stack listener so that it stops receiving callbacks. */
+ @Override
+ public void unregisterTaskStackListener(ITaskStackListener listener) {
+ mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
+ "unregisterTaskStackListener()");
+ mAm.mTaskChangeNotificationController.unregisterTaskStackListener(listener);
+ }
+
+ private void reportCurKeyguardUsageEventLocked(boolean keyguardShowing) {
+ mAm.reportGlobalUsageEventLocked(keyguardShowing
+ ? UsageEvents.Event.KEYGUARD_SHOWN
+ : UsageEvents.Event.KEYGUARD_HIDDEN);
+ }
+
+ @Override
+ public boolean requestAssistContextExtras(int requestType, IAssistDataReceiver receiver,
+ Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
+ return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
+ activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
+ PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
+ }
+
+ @Override
+ public boolean requestAutofillData(IAssistDataReceiver receiver, Bundle receiverExtras,
+ IBinder activityToken, int flags) {
+ return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
+ receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
+ null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
+ }
+
+ @Override
+ public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
+ Bundle args) {
+ return enqueueAssistContext(requestType, intent, hint, null, null, null,
+ true /* focused */, true /* newSessionId */, userHandle, args,
+ PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
+ }
+
+ @Override
+ public Bundle getAssistContextExtras(int requestType) {
+ PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
+ null, null, true /* focused */, true /* newSessionId */,
+ UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
+ if (pae == null) {
+ return null;
+ }
+ synchronized (pae) {
+ while (!pae.haveResult) {
+ try {
+ pae.wait();
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+ synchronized (mGlobalLock) {
+ buildAssistBundleLocked(pae, pae.result);
+ mPendingAssistExtras.remove(pae);
+ mAm.mUiHandler.removeCallbacks(pae);
+ }
+ return pae.extras;
+ }
+
+ private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
+ IAssistDataReceiver receiver, Bundle receiverExtras, IBinder activityToken,
+ boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
+ int flags) {
+ mAm.enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
+ "enqueueAssistContext()");
+
+ synchronized (mGlobalLock) {
+ ActivityRecord activity = mAm.getFocusedStack().getTopActivity();
+ if (activity == null) {
+ Slog.w(TAG, "getAssistContextExtras failed: no top activity");
+ return null;
+ }
+ if (activity.app == null || activity.app.thread == null) {
+ Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
+ return null;
+ }
+ if (focused) {
+ if (activityToken != null) {
+ ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
+ if (activity != caller) {
+ Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
+ + " is not current top " + activity);
+ return null;
+ }
+ }
+ } else {
+ activity = ActivityRecord.forTokenLocked(activityToken);
+ if (activity == null) {
+ Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
+ + " couldn't be found");
+ return null;
+ }
+ if (activity.app == null || activity.app.thread == null) {
+ Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
+ return null;
+ }
+ }
+
+ PendingAssistExtras pae;
+ Bundle extras = new Bundle();
+ if (args != null) {
+ extras.putAll(args);
+ }
+ extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
+ extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
+
+ pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
+ userHandle);
+ pae.isHome = activity.isActivityTypeHome();
+
+ // Increment the sessionId if necessary
+ if (newSessionId) {
+ mViSessionId++;
+ }
+ try {
+ activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
+ mViSessionId, flags);
+ mPendingAssistExtras.add(pae);
+ mAm.mUiHandler.postDelayed(pae, timeout);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
+ return null;
+ }
+ return pae;
+ }
+ }
+
+ private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
+ if (result != null) {
+ pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
+ }
+ if (pae.hint != null) {
+ pae.extras.putBoolean(pae.hint, true);
+ }
+ }
+
+ private void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
+ IAssistDataReceiver receiver;
+ synchronized (mGlobalLock) {
+ mPendingAssistExtras.remove(pae);
+ receiver = pae.receiver;
+ }
+ if (receiver != null) {
+ // Caller wants result sent back to them.
+ Bundle sendBundle = new Bundle();
+ // At least return the receiver extras
+ sendBundle.putBundle(ASSIST_KEY_RECEIVER_EXTRAS, pae.receiverExtras);
+ try {
+ pae.receiver.onHandleAssistData(sendBundle);
+ } catch (RemoteException e) {
+ }
+ }
+ }
+
+ public class PendingAssistExtras extends Binder implements Runnable {
+ public final ActivityRecord activity;
+ public boolean isHome;
+ public final Bundle extras;
+ public final Intent intent;
+ public final String hint;
+ public final IAssistDataReceiver receiver;
+ public final int userHandle;
+ public boolean haveResult = false;
+ public Bundle result = null;
+ public AssistStructure structure = null;
+ public AssistContent content = null;
+ public Bundle receiverExtras;
+
+ public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
+ String _hint, IAssistDataReceiver _receiver, Bundle _receiverExtras,
+ int _userHandle) {
+ activity = _activity;
+ extras = _extras;
+ intent = _intent;
+ hint = _hint;
+ receiver = _receiver;
+ receiverExtras = _receiverExtras;
+ userHandle = _userHandle;
+ }
+
+ @Override
+ public void run() {
+ Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
+ synchronized (this) {
+ haveResult = true;
+ notifyAll();
+ }
+ pendingAssistExtrasTimedOut(this);
+ }
+ }
+
+ @Override
+ public boolean isAssistDataAllowedOnCurrentActivity() {
+ int userId;
+ synchronized (mGlobalLock) {
+ final ActivityStack focusedStack = mAm.getFocusedStack();
+ if (focusedStack == null || focusedStack.isActivityTypeAssistant()) {
+ return false;
+ }
+
+ final ActivityRecord activity = focusedStack.getTopActivity();
+ if (activity == null) {
+ return false;
+ }
+ userId = activity.userId;
+ }
+ return !DevicePolicyCache.getInstance().getScreenCaptureDisabled(userId);
+ }
+
+ @Override
+ public boolean showAssistFromActivity(IBinder token, Bundle args) {
+ long ident = Binder.clearCallingIdentity();
+ try {
+ synchronized (mGlobalLock) {
+ ActivityRecord caller = ActivityRecord.forTokenLocked(token);
+ ActivityRecord top = mAm.getFocusedStack().getTopActivity();
+ 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;
+ }
+ }
+
+ @Override
+ public ComponentName getActivityClassForToken(IBinder token) {
+ synchronized (mGlobalLock) {
+ ActivityRecord r = ActivityRecord.isInStackLocked(token);
+ if (r == null) {
+ return null;
+ }
+ return r.intent.getComponent();
+ }
+ }
+
+ @Override
+ public String getPackageForToken(IBinder token) {
+ synchronized (mGlobalLock) {
+ ActivityRecord r = ActivityRecord.isInStackLocked(token);
+ if (r == null) {
+ return null;
+ }
+ return r.packageName;
+ }
+ }
+
+ @Override
+ public void showLockTaskEscapeMessage(IBinder token) {
+ synchronized (mGlobalLock) {
+ final ActivityRecord r = ActivityRecord.forTokenLocked(token);
+ if (r == null) {
+ return;
+ }
+ mAm.getLockTaskController().showLockTaskToast();
+ }
+ }
+
+ @Override
+ public void keyguardGoingAway(int flags) {
+ mAm.enforceNotIsolatedCaller("keyguardGoingAway");
+ final long token = Binder.clearCallingIdentity();
+ try {
+ synchronized (mGlobalLock) {
+ mAm.mKeyguardController.keyguardGoingAway(flags);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ /**
+ * Try to place task to provided position. The final position might be different depending on
+ * current user and stacks state. The task will be moved to target stack if it's currently in
+ * different stack.
+ */
+ @Override
+ public void positionTaskInStack(int taskId, int stackId, int position) {
+ mAm.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
+ synchronized (mGlobalLock) {
+ long ident = Binder.clearCallingIdentity();
+ try {
+ if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
+ + taskId + " in stackId=" + stackId + " at position=" + position);
+ final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
+ if (task == null) {
+ throw new IllegalArgumentException("positionTaskInStack: no task for id="
+ + taskId);
+ }
+
+ final ActivityStack stack = mStackSupervisor.getStack(stackId);
+
+ if (stack == null) {
+ throw new IllegalArgumentException("positionTaskInStack: no stack for id="
+ + stackId);
+ }
+ if (!stack.isActivityTypeStandardOrUndefined()) {
+ throw new IllegalArgumentException("positionTaskInStack: Attempt to change"
+ + " the position of task " + taskId + " in/to non-standard stack");
+ }
+
+ // TODO: Have the callers of this API call a separate reparent method if that is
+ // what they intended to do vs. having this method also do reparenting.
+ if (task.getStack() == stack) {
+ // Change position in current stack.
+ stack.positionChildAt(task, position);
+ } else {
+ // Reparent to new stack.
+ task.reparent(stack, position, REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE,
+ !DEFER_RESUME, "positionTaskInStack");
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+ }
+
+ @Override
+ public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
+ int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
+ if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
+ + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
+ synchronized (mGlobalLock) {
+ ActivityRecord record = ActivityRecord.isInStackLocked(token);
+ if (record == null) {
+ throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
+ + "found for: " + token);
+ }
+ record.setSizeConfigurations(horizontalSizeConfiguration,
+ verticalSizeConfigurations, smallestSizeConfigurations);
+ }
+ }
+
+ /**
+ * Dismisses split-screen multi-window mode.
+ * @param toTop If true the current primary split-screen stack will be placed or left on top.
+ */
+ @Override
+ public void dismissSplitScreenMode(boolean toTop) {
+ mAm.enforceCallerIsRecentsOrHasPermission(
+ MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()");
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ synchronized (mGlobalLock) {
+ final ActivityStack stack =
+ mStackSupervisor.getDefaultDisplay().getSplitScreenPrimaryStack();
+ if (stack == null) {
+ Slog.w(TAG, "dismissSplitScreenMode: primary split-screen stack not found.");
+ return;
+ }
+
+ if (toTop) {
+ // Caller wants the current split-screen primary stack to be the top stack after
+ // it goes fullscreen, so move it to the front.
+ stack.moveToFront("dismissSplitScreenMode");
+ } else if (mStackSupervisor.isFocusedStack(stack)) {
+ // In this case the current split-screen primary stack shouldn't be the top
+ // stack after it goes fullscreen, but it current has focus, so we move the
+ // focus to the top-most split-screen secondary stack next to it.
+ final ActivityStack otherStack = stack.getDisplay().getTopStackInWindowingMode(
+ WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
+ if (otherStack != null) {
+ otherStack.moveToFront("dismissSplitScreenMode_other");
+ }
+ }
+
+ stack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ /**
+ * Dismisses Pip
+ * @param animate True if the dismissal should be animated.
+ * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
+ * default animation duration should be used.
+ */
+ @Override
+ public void dismissPip(boolean animate, int animationDuration) {
+ mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ synchronized (mGlobalLock) {
+ final PinnedActivityStack stack =
+ mStackSupervisor.getDefaultDisplay().getPinnedStack();
+ if (stack == null) {
+ Slog.w(TAG, "dismissPip: pinned stack not found.");
+ return;
+ }
+ if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
+ throw new IllegalArgumentException("Stack: " + stack
+ + " doesn't support animated resize.");
+ }
+ if (animate) {
+ stack.animateResizePinnedStack(null /* sourceHintBounds */,
+ null /* destBounds */, animationDuration, false /* fromFullscreen */);
+ } else {
+ mStackSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
+ }
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ @Override
+ public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
+ mAm.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
+ synchronized (mGlobalLock) {
+ mSuppressResizeConfigChanges = suppress;
+ }
+ }
+
+ /**
+ * NOTE: For the pinned stack, this method is usually called after the bounds animation has
+ * animated the stack to the fullscreen, but can also be called if we are relaunching an
+ * activity and clearing the task at the same time.
+ */
+ @Override
+ // TODO: API should just be about changing windowing modes...
+ public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
+ mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
+ "moveTasksToFullscreenStack()");
+ synchronized (mGlobalLock) {
+ final long origId = Binder.clearCallingIdentity();
+ try {
+ final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
+ if (stack != null){
+ if (!stack.isActivityTypeStandardOrUndefined()) {
+ throw new IllegalArgumentException(
+ "You can't move tasks from non-standard stacks.");
+ }
+ mStackSupervisor.moveTasksToFullscreenStackLocked(stack, onTop);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(origId);
+ }
+ }
+ }
+
+ /**
+ * Moves the top activity in the input stackId to the pinned stack.
+ *
+ * @param stackId Id of stack to move the top activity to pinned stack.
+ * @param bounds Bounds to use for pinned stack.
+ *
+ * @return True if the top activity of the input stack was successfully moved to the pinned
+ * stack.
+ */
+ @Override
+ public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
+ mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
+ "moveTopActivityToPinnedStack()");
+ synchronized (mGlobalLock) {
+ if (!mAm.mSupportsPictureInPicture) {
+ throw new IllegalStateException("moveTopActivityToPinnedStack:"
+ + "Device doesn't support picture-in-picture mode");
+ }
+
+ long ident = Binder.clearCallingIdentity();
+ try {
+ return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+ }
+
+ @Override
+ public boolean isInMultiWindowMode(IBinder token) {
+ final long origId = Binder.clearCallingIdentity();
+ try {
+ synchronized (mGlobalLock) {
+ final ActivityRecord r = ActivityRecord.isInStackLocked(token);
+ if (r == null) {
+ return false;
+ }
+ // An activity is consider to be in multi-window mode if its task isn't fullscreen.
+ return r.inMultiWindowMode();
+ }
+ } finally {
+ Binder.restoreCallingIdentity(origId);
+ }
+ }
+
+ @Override
+ public boolean isInPictureInPictureMode(IBinder token) {
+ final long origId = Binder.clearCallingIdentity();
+ try {
+ synchronized (mGlobalLock) {
+ return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
+ }
+ } finally {
+ Binder.restoreCallingIdentity(origId);
+ }
+ }
+
+ private boolean isInPictureInPictureMode(ActivityRecord r) {
+ if (r == null || r.getStack() == null || !r.inPinnedWindowingMode()
+ || r.getStack().isInStackLocked(r) == null) {
+ return false;
+ }
+
+ // If we are animating to fullscreen then we have already dispatched the PIP mode
+ // changed, so we should reflect that check here as well.
+ final PinnedActivityStack stack = r.getStack();
+ final PinnedStackWindowController windowController = stack.getWindowContainerController();
+ return !windowController.isAnimatingBoundsToFullscreen();
+ }
+
+ @Override
+ public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
+ final long origId = Binder.clearCallingIdentity();
+ try {
+ synchronized (mGlobalLock) {
+ final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
+ "enterPictureInPictureMode", token, params);
+
+ // If the activity is already in picture in picture mode, then just return early
+ if (isInPictureInPictureMode(r)) {
+ return true;
+ }
+
+ // Activity supports picture-in-picture, now check that we can enter PiP at this
+ // point, if it is
+ if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
+ false /* beforeStopping */)) {
+ return false;
+ }
+
+ final Runnable enterPipRunnable = () -> {
+ // Only update the saved args from the args that are set
+ r.pictureInPictureArgs.copyOnlySet(params);
+ final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
+ final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
+ // Adjust the source bounds by the insets for the transition down
+ final Rect sourceBounds = new Rect(r.pictureInPictureArgs.getSourceRectHint());
+ mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio,
+ "enterPictureInPictureMode");
+ final PinnedActivityStack stack = r.getStack();
+ stack.setPictureInPictureAspectRatio(aspectRatio);
+ stack.setPictureInPictureActions(actions);
+ MetricsLoggerWrapper.logPictureInPictureEnter(mContext, r.appInfo.uid,
+ r.shortComponentName, r.supportsEnterPipOnTaskSwitch);
+ logPictureInPictureArgs(params);
+ };
+
+ if (mAm.isKeyguardLocked()) {
+ // If the keyguard is showing or occluded, then try and dismiss it before
+ // entering picture-in-picture (this will prompt the user to authenticate if the
+ // device is currently locked).
+ dismissKeyguard(token, new KeyguardDismissCallback() {
+ @Override
+ public void onDismissSucceeded() throws RemoteException {
+ mAm.mHandler.post(enterPipRunnable);
+ }
+ }, null /* message */);
+ } else {
+ // Enter picture in picture immediately otherwise
+ enterPipRunnable.run();
+ }
+ return true;
+ }
+ } 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.pictureInPictureArgs.copyOnlySet(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 PinnedActivityStack stack = r.getStack();
+ if (!stack.isAnimatingBoundsToFullscreen()) {
+ stack.setPictureInPictureAspectRatio(
+ r.pictureInPictureArgs.getAspectRatio());
+ stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
+ }
+ }
+ logPictureInPictureArgs(params);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(origId);
+ }
+ }
+
+ @Override
+ public int getMaxNumPictureInPictureActions(IBinder token) {
+ // Currently, this is a static constant, but later, we may change this to be dependent on
+ // the context of the activity
+ return 3;
+ }
+
+ private void logPictureInPictureArgs(PictureInPictureParams params) {
+ if (params.hasSetActions()) {
+ MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
+ params.getActions().size());
+ }
+ if (params.hasSetAspectRatio()) {
+ LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
+ lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
+ MetricsLogger.action(lm);
+ }
+ }
+
+ /**
+ * 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 (!mAm.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()
+ && !mAm.mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
+ 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(getMaxNumPictureInPictureActions(token));
+
+ return r;
+ }
+
+ @Override
+ public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
+ mAm.enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
+ synchronized (mGlobalLock) {
+ ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
+ if (r == null) {
+ throw new IllegalArgumentException("Activity does not exist; token="
+ + activityToken);
+ }
+ return r.getUriPermissionsLocked().getExternalTokenLocked();
+ }
+ }
+
+ @Override
+ public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
+ Rect tempDockedTaskInsetBounds,
+ Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
+ mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeDockedStack()");
+ long ident = Binder.clearCallingIdentity();
+ try {
+ synchronized (mGlobalLock) {
+ mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
+ tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
+ PRESERVE_WINDOWS);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ @Override
+ public void setSplitScreenResizing(boolean resizing) {
+ mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setSplitScreenResizing()");
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ synchronized (mGlobalLock) {
+ mStackSupervisor.setSplitScreenResizing(resizing);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ @Override
+ public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
+ mAm.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.userId)) !=
+ 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 == mStackSupervisor.getResumedActivityLocked()) {
+ mAm.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 = mAm.getFocusedStack().getTopActivity();
+ if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
+ throw new SecurityException("Only focused activity can call startVoiceInteraction");
+ }
+ if (mAm.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();
+ }
+
+ /** Notifies all listeners when the pinned stack animation starts. */
+ @Override
+ public void notifyPinnedStackAnimationStarted() {
+ mAm.mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
+ }
+
+ /** Notifies all listeners when the pinned stack animation ends. */
+ @Override
+ public void notifyPinnedStackAnimationEnded() {
+ mAm.mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
+ }
+
+ @Override
+ public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
+ mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()");
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ synchronized (mGlobalLock) {
+ mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ @Override
+ public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
+ mAm.enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
+
+ synchronized (mGlobalLock) {
+ // Check if display is initialized in AM.
+ if (!mStackSupervisor.isDisplayAdded(displayId)) {
+ // Call might come when display is not yet added or has already been removed.
+ if (DEBUG_CONFIGURATION) {
+ Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
+ + displayId);
+ }
+ return false;
+ }
+
+ if (values == null && mAm.mWindowManager != null) {
+ // sentinel: fetch the current configuration from the window manager
+ values = mAm.mWindowManager.computeNewConfiguration(displayId);
+ }
+
+ if (mAm.mWindowManager != null) {
+ // Update OOM levels based on display size.
+ mAm.mProcessList.applyDisplaySize(mAm.mWindowManager);
+ }
+
+ final long origId = Binder.clearCallingIdentity();
+ try {
+ if (values != null) {
+ Settings.System.clearConfiguration(values);
+ }
+ mAm.updateDisplayOverrideConfigurationLocked(values, null /* starting */,
+ false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
+ return mTmpUpdateConfigurationResult.changes != 0;
+ } finally {
+ Binder.restoreCallingIdentity(origId);
+ }
+ }
+ }
+
+ @Override
+ public boolean updateConfiguration(Configuration values) {
+ mAm.enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
+
+ synchronized (mGlobalLock) {
+ if (values == null && mAm.mWindowManager != null) {
+ // sentinel: fetch the current configuration from the window manager
+ values = mAm.mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
+ }
+
+ if (mAm.mWindowManager != null) {
+ // Update OOM levels based on display size.
+ mAm.mProcessList.applyDisplaySize(mAm.mWindowManager);
+ }
+
+ final long origId = Binder.clearCallingIdentity();
+ try {
+ if (values != null) {
+ Settings.System.clearConfiguration(values);
+ }
+ mAm.updateConfigurationLocked(values, null, false, false /* persistent */,
+ UserHandle.USER_NULL, false /* deferResume */,
+ mTmpUpdateConfigurationResult);
+ return mTmpUpdateConfigurationResult.changes != 0;
+ } finally {
+ Binder.restoreCallingIdentity(origId);
+ }
+ }
+ }
+
+ @Override
+ public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback,
+ CharSequence message) {
+ if (message != null) {
+ mAm.enforceCallingPermission(
+ Manifest.permission.SHOW_KEYGUARD_MESSAGE, "dismissKeyguard()");
+ }
+ final long callingId = Binder.clearCallingIdentity();
+ try {
+ synchronized (mGlobalLock) {
+ mAm.mKeyguardController.dismissKeyguard(token, callback, message);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(callingId);
+ }
+ }
+
+ @Override
+ public void cancelTaskWindowTransition(int taskId) {
+ mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
+ "cancelTaskWindowTransition()");
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ synchronized (mGlobalLock) {
+ final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
+ MATCH_TASK_IN_STACKS_ONLY);
+ if (task == null) {
+ Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
+ return;
+ }
+ task.cancelWindowTransition();
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ @Override
+ public ActivityManager.TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
+ mAm.enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ final TaskRecord task;
+ synchronized (mGlobalLock) {
+ task = mStackSupervisor.anyTaskForIdLocked(taskId,
+ MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
+ if (task == null) {
+ Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
+ return null;
+ }
+ }
+ // Don't call this while holding the lock as this operation might hit the disk.
+ return task.getSnapshot(reducedResolution);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ @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);
+ }
+ }
+ }
+
+ /** Return the user id of the last resumed activity. */
+ @Override
+ public @UserIdInt
+ int getLastResumedActivityUserId() {
+ mAm.enforceCallingPermission(
+ Manifest.permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
+ synchronized (mGlobalLock) {
+ if (mAm.mLastResumedActivity == null) {
+ return mAm.mUserController.getCurrentUserId();
+ }
+ return mAm.mLastResumedActivity.userId;
+ }
+ }
+
+ @Override
+ public void updateLockTaskFeatures(int userId, int flags) {
+ final int callingUid = Binder.getCallingUid();
+ if (callingUid != 0 && callingUid != SYSTEM_UID) {
+ mAm.enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
+ "updateLockTaskFeatures()");
+ }
+ synchronized (mGlobalLock) {
+ if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Allowing features " + userId + ":0x" +
+ Integer.toHexString(flags));
+ mAm.getLockTaskController().updateLockTaskFeatures(userId, flags);
+ }
+ }
+
+ @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 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) {
+ mAm.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
+ "registerRemoteAnimations");
+ definition.setCallingPid(Binder.getCallingPid());
+ 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 registerRemoteAnimationForNextActivityStart(String packageName,
+ RemoteAnimationAdapter adapter) {
+ mAm.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
+ "registerRemoteAnimationForNextActivityStart");
+ adapter.setCallingPid(Binder.getCallingPid());
+ synchronized (mGlobalLock) {
+ final long origId = Binder.clearCallingIdentity();
+ try {
+ mAm.getActivityStartController().registerRemoteAnimationForNextActivityStart(
+ packageName, adapter);
+ } finally {
+ Binder.restoreCallingIdentity(origId);
+ }
+ }
+ }
+
+ /** @see android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning */
+ @Override
+ public void alwaysShowUnsupportedCompileSdkWarning(ComponentName activity) {
+ synchronized (mGlobalLock) {
+ final long origId = Binder.clearCallingIdentity();
+ try {
+ mAm.mAppWarnings.alwaysShowUnsupportedCompileSdkWarning(activity);
+ } finally {
+ Binder.restoreCallingIdentity(origId);
+ }
+ }
+ }
}
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
index a6dafbb..75090d4 100644
--- a/services/core/java/com/android/server/am/AppErrors.java
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -471,7 +471,7 @@
mService.removeProcessLocked(r, false, true, "crash");
if (task != null) {
try {
- mService.startActivityFromRecents(task.taskId,
+ mService.mActivityTaskManager.startActivityFromRecents(task.taskId,
ActivityOptions.makeBasic().toBundle());
} catch (IllegalArgumentException e) {
// Hmm, that didn't work, app might have crashed before creating a
diff --git a/services/core/java/com/android/server/am/AssistDataRequester.java b/services/core/java/com/android/server/am/AssistDataRequester.java
index 9f7621f..14d1498 100644
--- a/services/core/java/com/android/server/am/AssistDataRequester.java
+++ b/services/core/java/com/android/server/am/AssistDataRequester.java
@@ -21,6 +21,7 @@
import static android.app.AppOpsManager.MODE_ALLOWED;
import static android.app.AppOpsManager.OP_NONE;
+import android.app.ActivityTaskManager;
import android.app.AppOpsManager;
import android.app.IActivityManager;
import android.app.IAssistDataReceiver;
@@ -163,7 +164,8 @@
// Ensure that the current activity supports assist data
boolean isAssistDataAllowed = false;
try {
- isAssistDataAllowed = mService.isAssistDataAllowedOnCurrentActivity();
+ isAssistDataAllowed =
+ ActivityTaskManager.getService().isAssistDataAllowedOnCurrentActivity();
} catch (RemoteException e) {
// Should never happen
}
@@ -188,9 +190,9 @@
Bundle receiverExtras = new Bundle();
receiverExtras.putInt(KEY_RECEIVER_EXTRA_INDEX, i);
receiverExtras.putInt(KEY_RECEIVER_EXTRA_COUNT, numActivities);
- if (mService.requestAssistContextExtras(ASSIST_CONTEXT_FULL, this,
- receiverExtras, topActivity, /* focused= */ i == 0,
- /* newSessionId= */ i == 0)) {
+ if (ActivityTaskManager.getService().requestAssistContextExtras(
+ ASSIST_CONTEXT_FULL, this, receiverExtras, topActivity,
+ /* focused= */ i == 0, /* newSessionId= */ i == 0)) {
mPendingDataCount++;
} else if (i == 0) {
// Wasn't allowed... given that, let's not do the screenshot either.
diff --git a/services/core/java/com/android/server/am/LaunchParamsController.java b/services/core/java/com/android/server/am/LaunchParamsController.java
index 7ab7f98..4330d2c 100644
--- a/services/core/java/com/android/server/am/LaunchParamsController.java
+++ b/services/core/java/com/android/server/am/LaunchParamsController.java
@@ -125,7 +125,7 @@
try {
if (mTmpParams.hasPreferredDisplay()
&& mTmpParams.mPreferredDisplayId != task.getStack().getDisplay().mDisplayId) {
- mService.moveStackToDisplay(task.getStackId(), mTmpParams.mPreferredDisplayId);
+ mService.mActivityTaskManager.moveStackToDisplay(task.getStackId(), mTmpParams.mPreferredDisplayId);
}
if (mTmpParams.hasWindowingMode()
diff --git a/services/core/java/com/android/server/am/LockTaskController.java b/services/core/java/com/android/server/am/LockTaskController.java
index 151ef49..4fd01cd 100644
--- a/services/core/java/com/android/server/am/LockTaskController.java
+++ b/services/core/java/com/android/server/am/LockTaskController.java
@@ -361,7 +361,7 @@
* @param task the task that requested the end of lock task mode ({@code null} for quitting app
* pinning mode)
* @param isSystemCaller indicates whether this request comes from the system via
- * {@link ActivityManagerService#stopSystemLockTaskMode()}. If
+ * {@link ActivityTaskManagerService#stopSystemLockTaskMode()}. If
* {@code true}, it means the user intends to stop pinned mode through UI;
* otherwise, it's called by an app and we need to stop locked or pinned
* mode, subject to checks.
@@ -509,7 +509,7 @@
*
* @param task the task that should be locked.
* @param isSystemCaller indicates whether this request was initiated by the system via
- * {@link ActivityManagerService#startSystemLockTaskMode(int)}. If
+ * {@link ActivityTaskManagerService#startSystemLockTaskMode(int)}. If
* {@code true}, this intends to start pinned mode; otherwise, we look
* at the calling task's mLockTaskAuth to decide which mode to start.
* @param callingUid the caller that requested the launch of lock task mode.
diff --git a/services/core/java/com/android/server/am/PinnedActivityStack.java b/services/core/java/com/android/server/am/PinnedActivityStack.java
index 2726979..4062f45 100644
--- a/services/core/java/com/android/server/am/PinnedActivityStack.java
+++ b/services/core/java/com/android/server/am/PinnedActivityStack.java
@@ -55,7 +55,7 @@
void animateResizePinnedStack(Rect sourceHintBounds, Rect toBounds, int animationDuration,
boolean fromFullscreen) {
if (skipResizeAnimation(toBounds == null /* toFullscreen */)) {
- mService.moveTasksToFullscreenStack(mStackId, true /* onTop */);
+ mService.mActivityTaskManager.moveTasksToFullscreenStack(mStackId, true /* onTop */);
} else {
getWindowContainerController().animateResizePinnedStack(toBounds, sourceHintBounds,
animationDuration, fromFullscreen);
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index c841081..0ea49b2 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -486,7 +486,7 @@
// TODO: Consolidate this with the resize() method below.
@Override
public void requestResize(Rect bounds, int resizeMode) {
- mService.resizeTask(taskId, bounds, resizeMode);
+ mService.mActivityTaskManager.resizeTask(taskId, bounds, resizeMode);
}
boolean resize(Rect bounds, int resizeMode, boolean preserveWindow, boolean deferResume) {
@@ -1745,7 +1745,7 @@
* @param bounds The bounds of the task.
* @param insetBounds The bounds used to calculate the system insets, which is used here to
* subtract the navigation bar/status bar size from the screen size reported
- * to the application. See {@link IActivityManager#resizeDockedStack}.
+ * to the application. See {@link IActivityTaskManager#resizeDockedStack}.
* @return True if the override configuration was updated.
*/
boolean updateOverrideConfiguration(Rect bounds, @Nullable Rect insetBounds) {
diff --git a/services/core/java/com/android/server/display/BrightnessTracker.java b/services/core/java/com/android/server/display/BrightnessTracker.java
index a568fe3..c473ef2 100644
--- a/services/core/java/com/android/server/display/BrightnessTracker.java
+++ b/services/core/java/com/android/server/display/BrightnessTracker.java
@@ -19,6 +19,7 @@
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.ActivityManager;
+import android.app.ActivityTaskManager;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
@@ -937,7 +938,7 @@
}
public ActivityManager.StackInfo getFocusedStack() throws RemoteException {
- return ActivityManager.getService().getFocusedStackInfo();
+ return ActivityTaskManager.getService().getFocusedStackInfo();
}
public void scheduleIdleJob(Context context) {
diff --git a/services/core/java/com/android/server/display/DisplayTransformManager.java b/services/core/java/com/android/server/display/DisplayTransformManager.java
index 57a4f0d..d6931e0 100644
--- a/services/core/java/com/android/server/display/DisplayTransformManager.java
+++ b/services/core/java/com/android/server/display/DisplayTransformManager.java
@@ -17,6 +17,7 @@
package com.android.server.display;
import android.app.ActivityManager;
+import android.app.ActivityTaskManager;
import android.opengl.Matrix;
import android.os.IBinder;
import android.os.Parcel;
@@ -309,7 +310,7 @@
private void updateConfiguration() {
try {
- ActivityManager.getService().updateConfiguration(null);
+ ActivityTaskManager.getService().updateConfiguration(null);
} catch (RemoteException e) {
Log.e(TAG, "Could not update configuration", e);
}
diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java
index 06329e57..8e77820 100644
--- a/services/core/java/com/android/server/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java
@@ -25,9 +25,11 @@
import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;
+import android.app.ActivityTaskManager;
import android.app.AlarmManager;
import android.app.AppOpsManager;
import android.app.IActivityManager;
+import android.app.IActivityTaskManager;
import android.app.PendingIntent;
import android.app.SynchronousUserSwitchObserver;
import android.app.TaskStackListener;
@@ -140,6 +142,7 @@
private IBiometricsFingerprint mDaemon;
private IStatusBarService mStatusBarService;
private final IActivityManager mActivityManager;
+ private final IActivityTaskManager mActivityTaskManager;
private final PowerManager mPowerManager;
private final AlarmManager mAlarmManager;
private final UserManager mUserManager;
@@ -229,7 +232,8 @@
if (isKeyguard(currentClient)) {
return; // Keyguard is always allowed
}
- List<ActivityManager.RunningTaskInfo> runningTasks = mActivityManager.getTasks(1);
+ List<ActivityManager.RunningTaskInfo> runningTasks =
+ mActivityTaskManager.getTasks(1);
if (!runningTasks.isEmpty()) {
final String topPackage = runningTasks.get(0).topActivity.getPackageName();
if (!topPackage.contentEquals(currentClient)) {
@@ -261,6 +265,8 @@
ServiceManager.getService(Context.STATUS_BAR_SERVICE));
mActivityManager = ((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE))
.getService();
+ mActivityTaskManager = ((ActivityTaskManager) context.getSystemService(
+ Context.ACTIVITY_TASK_SERVICE)).getService();
}
@Override
@@ -871,7 +877,7 @@
@Override
public void onStart() {
try {
- mActivityManager.registerTaskStackListener(mTaskStackListener);
+ mActivityTaskManager.registerTaskStackListener(mTaskStackListener);
} catch (RemoteException e) {
Slog.e(TAG, "Could not register task stack listener", e);
}
@@ -880,7 +886,7 @@
@Override
public void onStop() {
try {
- mActivityManager.unregisterTaskStackListener(mTaskStackListener);
+ mActivityTaskManager.unregisterTaskStackListener(mTaskStackListener);
} catch (RemoteException e) {
Slog.e(TAG, "Could not unregister task stack listener", e);
}
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 8b0375f..32825f7 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -156,6 +156,7 @@
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
import android.app.ActivityManagerInternal.SleepToken;
+import android.app.ActivityTaskManager;
import android.app.ActivityThread;
import android.app.AppOpsManager;
import android.app.IUiModeManager;
@@ -7987,7 +7988,7 @@
sendCloseSystemWindows();
Intent dock = createHomeDockIntent();
if (dock != null) {
- int result = ActivityManager.getService()
+ int result = ActivityTaskManager.getService()
.startActivityAsUser(null, null, dock,
dock.resolveTypeIfNeeded(mContext.getContentResolver()),
null, null, 0,
@@ -7998,7 +7999,7 @@
}
}
}
- int result = ActivityManager.getService()
+ int result = ActivityTaskManager.getService()
.startActivityAsUser(null, null, mHomeIntent,
mHomeIntent.resolveTypeIfNeeded(mContext.getContentResolver()),
null, null, 0,
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
index 81a8c55..1e0b52a 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
@@ -8,6 +8,7 @@
import static com.android.server.wm.KeyguardServiceDelegateProto.SHOWING;
import android.app.ActivityManager;
+import android.app.ActivityTaskManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -213,7 +214,7 @@
// There are no longer any keyguard windows on secondary displays, so pass
// INVALID_DISPLAY. All that means is that showWhenLocked activities on
// secondary displays now get to show.
- ActivityManager.getService().setLockScreenShown(true /* keyguardShowing */,
+ ActivityTaskManager.getService().setLockScreenShown(true /* keyguardShowing */,
false /* aodShowing */, INVALID_DISPLAY);
} catch (RemoteException e) {
// Local call.
diff --git a/services/core/java/com/android/server/search/SearchManagerService.java b/services/core/java/com/android/server/search/SearchManagerService.java
index c3fa823..bc1a12f 100644
--- a/services/core/java/com/android/server/search/SearchManagerService.java
+++ b/services/core/java/com/android/server/search/SearchManagerService.java
@@ -17,7 +17,9 @@
package com.android.server.search;
import android.app.ActivityManager;
+import android.app.ActivityTaskManager;
import android.app.IActivityManager;
+import android.app.IActivityTaskManager;
import android.app.ISearchManager;
import android.app.SearchManager;
import android.app.SearchableInfo;
@@ -307,7 +309,7 @@
Intent intent = new Intent(VoiceInteractionService.SERVICE_INTERFACE);
intent.setComponent(comp);
- IActivityManager am = ActivityManager.getService();
+ IActivityTaskManager am = ActivityTaskManager.getService();
if (args != null) {
args.putInt(Intent.EXTRA_KEY_EVENT, android.view.KeyEvent.KEYCODE_ASSIST);
}
diff --git a/services/core/java/com/android/server/wm/DragAndDropPermissionsHandler.java b/services/core/java/com/android/server/wm/DragAndDropPermissionsHandler.java
index 70478fe..51d5eea 100644
--- a/services/core/java/com/android/server/wm/DragAndDropPermissionsHandler.java
+++ b/services/core/java/com/android/server/wm/DragAndDropPermissionsHandler.java
@@ -17,6 +17,7 @@
package com.android.server.wm;
import android.app.ActivityManager;
+import android.app.ActivityTaskManager;
import android.content.ClipData;
import android.net.Uri;
import android.os.Binder;
@@ -61,7 +62,7 @@
mActivityToken = activityToken;
// Will throw if Activity is not found.
- IBinder permissionOwner = ActivityManager.getService().
+ IBinder permissionOwner = ActivityTaskManager.getService().
getUriPermissionOwnerForActivity(mActivityToken);
doTake(permissionOwner);
@@ -101,7 +102,7 @@
IBinder permissionOwner = null;
if (mActivityToken != null) {
try {
- permissionOwner = ActivityManager.getService().
+ permissionOwner = ActivityTaskManager.getService().
getUriPermissionOwnerForActivity(mActivityToken);
} catch (Exception e) {
// Activity is destroyed, permissions already revoked.
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 16277d5..2da77a1 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -218,7 +218,7 @@
}
}
- /** @see com.android.server.am.ActivityManagerService#positionTaskInStack(int, int, int). */
+ /** @see com.android.server.am.ActivityTaskManagerService#positionTaskInStack(int, int, int). */
void positionAt(int position) {
mStack.positionChildAt(position, this, false /* includingParents */);
}
@@ -298,7 +298,7 @@
/**
* Sets the bounds used to calculate the insets. See
- * {@link android.app.IActivityManager#resizeDockedStack} why this is needed.
+ * {@link android.app.IActivityTaskManager#resizeDockedStack} why this is needed.
*/
void setTempInsetBounds(Rect tempInsetBounds) {
if (tempInsetBounds != null) {
@@ -310,7 +310,7 @@
/**
* Gets the bounds used to calculate the insets. See
- * {@link android.app.IActivityManager#resizeDockedStack} why this is needed.
+ * {@link android.app.IActivityTaskManager#resizeDockedStack} why this is needed.
*/
void getTempInsetBounds(Rect out) {
out.set(mTempInsetBounds);
diff --git a/services/core/java/com/android/server/wm/TaskPositioner.java b/services/core/java/com/android/server/wm/TaskPositioner.java
index 223c666..30f46a0 100644
--- a/services/core/java/com/android/server/wm/TaskPositioner.java
+++ b/services/core/java/com/android/server/wm/TaskPositioner.java
@@ -30,6 +30,7 @@
import android.annotation.IntDef;
import android.app.IActivityManager;
+import android.app.IActivityTaskManager;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Looper;
@@ -94,7 +95,7 @@
static final float MIN_ASPECT = 1.2f;
private final WindowManagerService mService;
- private final IActivityManager mActivityManager;
+ private final IActivityTaskManager mActivityManager;
private WindowPositionerEventReceiver mInputEventReceiver;
private Display mDisplay;
private final DisplayMetrics mDisplayMetrics = new DisplayMetrics();
@@ -219,14 +220,14 @@
}
@VisibleForTesting
- TaskPositioner(WindowManagerService service, IActivityManager activityManager) {
+ TaskPositioner(WindowManagerService service, IActivityTaskManager activityManager) {
mService = service;
mActivityManager = activityManager;
}
/** Use {@link #create(WindowManagerService)} instead **/
TaskPositioner(WindowManagerService service) {
- this(service, service.mActivityManager);
+ this(service, service.mActivityTaskManager);
}
@VisibleForTesting
diff --git a/services/core/java/com/android/server/wm/TaskPositioningController.java b/services/core/java/com/android/server/wm/TaskPositioningController.java
index a3f4ee8..7d36650 100644
--- a/services/core/java/com/android/server/wm/TaskPositioningController.java
+++ b/services/core/java/com/android/server/wm/TaskPositioningController.java
@@ -21,6 +21,7 @@
import android.annotation.Nullable;
import android.app.IActivityManager;
+import android.app.IActivityTaskManager;
import android.os.RemoteException;
import android.os.Handler;
import android.os.Looper;
@@ -38,7 +39,7 @@
private final WindowManagerService mService;
private final InputManagerService mInputManager;
private final InputMonitor mInputMonitor;
- private final IActivityManager mActivityManager;
+ private final IActivityTaskManager mActivityManager;
private final Handler mHandler;
@GuardedBy("WindowManagerSerivce.mWindowMap")
@@ -53,7 +54,7 @@
}
TaskPositioningController(WindowManagerService service, InputManagerService inputManager,
- InputMonitor inputMonitor, IActivityManager activityManager, Looper looper) {
+ InputMonitor inputMonitor, IActivityTaskManager activityManager, Looper looper) {
mService = service;
mInputMonitor = inputMonitor;
mInputManager = inputManager;
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 731a06e..e6db6d9 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -1614,7 +1614,7 @@
}
try {
- mService.mActivityManager.resizePinnedStack(stackBounds, tempTaskBounds);
+ mService.mActivityTaskManager.resizePinnedStack(stackBounds, tempTaskBounds);
} catch (RemoteException e) {
// I don't believe you.
}
@@ -1647,7 +1647,7 @@
if (inPinnedWindowingMode()) {
try {
- mService.mActivityManager.notifyPinnedStackAnimationStarted();
+ mService.mActivityTaskManager.notifyPinnedStackAnimationStarted();
} catch (RemoteException e) {
// I don't believe you...
}
@@ -1689,9 +1689,9 @@
}
try {
- mService.mActivityManager.notifyPinnedStackAnimationEnded();
+ mService.mActivityTaskManager.notifyPinnedStackAnimationEnded();
if (moveToFullscreen) {
- mService.mActivityManager.moveTasksToFullscreenStack(mStackId,
+ mService.mActivityTaskManager.moveTasksToFullscreenStack(mStackId,
true /* onTop */);
}
} catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index df3b16c..c1753c0 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -116,9 +116,11 @@
import android.app.ActivityManager;
import android.app.ActivityManager.TaskSnapshot;
import android.app.ActivityManagerInternal;
+import android.app.ActivityTaskManager;
import android.app.ActivityThread;
import android.app.AppOpsManager;
import android.app.IActivityManager;
+import android.app.IActivityTaskManager;
import android.app.IAssistDataReceiver;
import android.app.admin.DevicePolicyCache;
import android.content.BroadcastReceiver;
@@ -427,6 +429,8 @@
final WindowManagerPolicy mPolicy;
final IActivityManager mActivityManager;
+ // TODO: Probably not needed once activities are fully in WM.
+ final IActivityTaskManager mActivityTaskManager;
final ActivityManagerInternal mAmInternal;
final AppOpsManager mAppOps;
@@ -859,7 +863,7 @@
}
if (atoken.mLaunchTaskBehind) {
try {
- mActivityManager.notifyLaunchTaskBehindComplete(atoken.token);
+ mActivityTaskManager.notifyLaunchTaskBehindComplete(atoken.token);
} catch (RemoteException e) {
}
atoken.mLaunchTaskBehind = false;
@@ -876,7 +880,7 @@
} else {
atoken.mEnteringAnimation = false;
try {
- mActivityManager.notifyEnterAnimationComplete(atoken.token);
+ mActivityTaskManager.notifyEnterAnimationComplete(atoken.token);
} catch (RemoteException e) {
}
}
@@ -1009,6 +1013,7 @@
AnimationThread.getHandler(), animationHandler);
mActivityManager = ActivityManager.getService();
+ mActivityTaskManager = ActivityTaskManager.getService();
mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);
AppOpsManager.OnOpChangedInternalListener opListener =
@@ -1066,7 +1071,7 @@
com.android.internal.R.bool.config_allowTheaterModeWakeFromWindowLayout);
mTaskPositioningController = new TaskPositioningController(
- this, mInputManager, mInputMonitor, mActivityManager, mH.getLooper());
+ this, mInputManager, mInputMonitor, mActivityTaskManager, mH.getLooper());
mDragDropController = new DragDropController(this, mH.getLooper());
LocalServices.addService(WindowManagerInternal.class, new LocalService());
@@ -4372,7 +4377,7 @@
*/
void sendNewConfiguration(int displayId) {
try {
- final boolean configUpdated = mActivityManager.updateDisplayOverrideConfiguration(
+ final boolean configUpdated = mActivityTaskManager.updateDisplayOverrideConfiguration(
null /* values */, displayId);
if (!configUpdated) {
// Something changed (E.g. device rotation), but no configuration update is needed.
@@ -4527,7 +4532,7 @@
}
try {
- mActivityManager.updateConfiguration(null);
+ mActivityTaskManager.updateConfiguration(null);
} catch (RemoteException e) {
}
@@ -4538,7 +4543,7 @@
}
try {
- mActivityManager.updateConfiguration(null);
+ mActivityTaskManager.updateConfiguration(null);
} catch (RemoteException e) {
}
@@ -4893,7 +4898,7 @@
case NOTIFY_ACTIVITY_DRAWN:
try {
- mActivityManager.notifyActivityDrawn((IBinder) msg.obj);
+ mActivityTaskManager.notifyActivityDrawn((IBinder) msg.obj);
} catch (RemoteException e) {
}
break;
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 1eb5617..cbe30cf 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -445,7 +445,7 @@
/**
* Usually empty. Set to the task's tempInsetFrame. See
- *{@link android.app.IActivityManager#resizeDockedStack}.
+ *{@link android.app.IActivityTaskManager#resizeDockedStack}.
*/
private final Rect mInsetFrame = new Rect();
@@ -2448,7 +2448,7 @@
try {
// Note: this calls into ActivityManager, so we must *not* hold the window
// manager lock while calling this.
- mService.mActivityManager.setSplitScreenResizing(false);
+ mService.mActivityTaskManager.setSplitScreenResizing(false);
} catch (RemoteException e) {
// Local call, shouldn't return RemoteException.
throw e.rethrowAsRuntimeException();
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index e605a49..414cf47 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -90,10 +90,12 @@
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
+import android.app.ActivityTaskManager;
import android.app.ActivityThread;
import android.app.AlarmManager;
import android.app.AppGlobals;
import android.app.IActivityManager;
+import android.app.IActivityTaskManager;
import android.app.IApplicationThread;
import android.app.IServiceConnection;
import android.app.Notification;
@@ -1865,6 +1867,10 @@
return ActivityManager.getService();
}
+ IActivityTaskManager getIActivityTaskManager() {
+ return ActivityTaskManager.getService();
+ }
+
ActivityManagerInternal getActivityManagerInternal() {
return LocalServices.getService(ActivityManagerInternal.class);
}
@@ -3286,8 +3292,7 @@
private void updateLockTaskFeaturesLocked(int flags, int userId) {
long ident = mInjector.binderClearCallingIdentity();
try {
- mInjector.getIActivityManager()
- .updateLockTaskFeatures(userId, flags);
+ mInjector.getIActivityTaskManager().updateLockTaskFeatures(userId, flags);
} catch (RemoteException e) {
// Not gonna happen.
} finally {
@@ -10155,7 +10160,7 @@
if (policy.mStatusBarDisabled != disabled) {
boolean isLockTaskMode = false;
try {
- isLockTaskMode = mInjector.getIActivityManager().getLockTaskModeState()
+ isLockTaskMode = mInjector.getIActivityTaskManager().getLockTaskModeState()
!= LOCK_TASK_MODE_NONE;
} catch (RemoteException e) {
Slog.e(LOG_TAG, "Failed to get LockTask mode");
diff --git a/services/tests/servicestests/src/com/android/server/am/AssistDataRequesterTest.java b/services/tests/servicestests/src/com/android/server/am/AssistDataRequesterTest.java
index ce88d84..0a436b9 100644
--- a/services/tests/servicestests/src/com/android/server/am/AssistDataRequesterTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/AssistDataRequesterTest.java
@@ -35,6 +35,7 @@
import android.app.AppOpsManager;
import android.app.IActivityManager;
+import android.app.IActivityTaskManager;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Bundle;
@@ -87,6 +88,7 @@
private Object mCallbacksLock;
private Handler mHandler;
private IActivityManager mAm;
+ private IActivityTaskManager mAtm;
private IWindowManager mWm;
private AppOpsManager mAppOpsManager;
@@ -104,6 +106,7 @@
public void setUp() throws Exception {
super.setUp();
mAm = mock(IActivityManager.class);
+ mAtm = mock(IActivityTaskManager.class);
mWm = mock(IWindowManager.class);
mAppOpsManager = mock(AppOpsManager.class);
mContext = InstrumentationRegistry.getContext();
@@ -125,7 +128,7 @@
}
});
return true;
- }).when(mAm).requestAssistContextExtras(anyInt(), any(), any(), any(), anyBoolean(),
+ }).when(mAtm).requestAssistContextExtras(anyInt(), any(), any(), any(), anyBoolean(),
anyBoolean());
doAnswer(invocation -> {
mHandler.post(() -> {
@@ -142,7 +145,7 @@
private void setupMocks(boolean currentActivityAssistAllowed, boolean assistStructureAllowed,
boolean assistScreenshotAllowed) throws Exception {
- doReturn(currentActivityAssistAllowed).when(mAm).isAssistDataAllowedOnCurrentActivity();
+ doReturn(currentActivityAssistAllowed).when(mAtm).isAssistDataAllowedOnCurrentActivity();
doReturn(assistStructureAllowed ? MODE_ALLOWED : MODE_ERRORED).when(mAppOpsManager)
.checkOpNoThrow(eq(OP_ASSIST_STRUCTURE), anyInt(), anyString());
doReturn(assistScreenshotAllowed ? MODE_ALLOWED : MODE_ERRORED).when(mAppOpsManager)
@@ -240,7 +243,7 @@
public void testDisallowAssistContextExtras_expectNullDataCallbacks() throws Exception {
setupMocks(CURRENT_ACTIVITY_ASSIST_ALLOWED, CALLER_ASSIST_STRUCTURE_ALLOWED,
CALLER_ASSIST_SCREENSHOT_ALLOWED);
- doReturn(false).when(mAm).requestAssistContextExtras(anyInt(), any(), any(), any(),
+ doReturn(false).when(mAtm).requestAssistContextExtras(anyInt(), any(), any(), any(),
anyBoolean(), anyBoolean());
mDataRequester.requestAssistData(createActivityList(5), FETCH_DATA, FETCH_SCREENSHOTS,
@@ -371,4 +374,4 @@
});
}
}
-}
\ No newline at end of file
+}
diff --git a/services/tests/servicestests/src/com/android/server/am/LaunchParamsControllerTests.java b/services/tests/servicestests/src/com/android/server/am/LaunchParamsControllerTests.java
index 161c287..93e0b5a 100644
--- a/services/tests/servicestests/src/com/android/server/am/LaunchParamsControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/LaunchParamsControllerTests.java
@@ -200,9 +200,9 @@
mController.registerModifier(positioner);
- doNothing().when(mService).moveStackToDisplay(anyInt(), anyInt());
+ doNothing().when(mService.mActivityTaskManager).moveStackToDisplay(anyInt(), anyInt());
mController.layoutTask(task, null /* windowLayout */);
- verify(mService, times(1)).moveStackToDisplay(eq(task.getStackId()),
+ verify(mService.mActivityTaskManager, times(1)).moveStackToDisplay(eq(task.getStackId()),
eq(params.mPreferredDisplayId));
}
diff --git a/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java b/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java
index 57c3bcb..af6686f 100644
--- a/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java
@@ -696,7 +696,7 @@
}
private void testRecentTasksApis(boolean expectCallable) {
- assertSecurityException(expectCallable, () -> mService.removeStack(INVALID_STACK_ID));
+ assertSecurityException(expectCallable, () -> mService.mActivityTaskManager.removeStack(INVALID_STACK_ID));
assertSecurityException(expectCallable,
() -> mService.mActivityTaskManager.removeStacksInWindowingModes(
new int[] {WINDOWING_MODE_UNDEFINED}));
@@ -712,52 +712,42 @@
assertSecurityException(expectCallable,
() -> mService.mActivityTaskManager.setTaskWindowingModeSplitScreenPrimary(0,
SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, true, true, new Rect(), true));
- assertSecurityException(expectCallable, () -> mService.dismissSplitScreenMode(true));
- assertSecurityException(expectCallable, () -> mService.dismissPip(true, 0));
+ assertSecurityException(expectCallable, () -> mService.mActivityTaskManager.dismissSplitScreenMode(true));
+ assertSecurityException(expectCallable, () -> mService.mActivityTaskManager.dismissPip(true, 0));
assertSecurityException(expectCallable,
- () -> mService.moveTopActivityToPinnedStack(INVALID_STACK_ID, new Rect()));
+ () -> mService.mActivityTaskManager.moveTopActivityToPinnedStack(INVALID_STACK_ID, new Rect()));
assertSecurityException(expectCallable,
() -> mService.resizeStack(INVALID_STACK_ID, new Rect(), true, true, true, 0));
assertSecurityException(expectCallable,
- () -> mService.resizeDockedStack(new Rect(), new Rect(), new Rect(), new Rect(),
+ () -> mService.mActivityTaskManager.resizeDockedStack(new Rect(), new Rect(), new Rect(), new Rect(),
new Rect()));
assertSecurityException(expectCallable,
- () -> mService.resizePinnedStack(new Rect(), new Rect()));
- assertSecurityException(expectCallable, () -> mService.getAllStackInfos());
+ () -> mService.mActivityTaskManager.resizePinnedStack(new Rect(), new Rect()));
+ assertSecurityException(expectCallable, () -> mService.mActivityTaskManager.getAllStackInfos());
assertSecurityException(expectCallable,
- () -> mService.getStackInfo(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_UNDEFINED));
+ () -> mService.mActivityTaskManager.getStackInfo(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_UNDEFINED));
assertSecurityException(expectCallable, () -> {
try {
- mService.getFocusedStackInfo();
+ mService.mActivityTaskManager.getFocusedStackInfo();
} catch (RemoteException e) {
// Ignore
}
});
assertSecurityException(expectCallable,
- () -> mService.moveTasksToFullscreenStack(INVALID_STACK_ID, true));
+ () -> mService.mActivityTaskManager.moveTasksToFullscreenStack(INVALID_STACK_ID, true));
assertSecurityException(expectCallable,
- () -> mService.startActivityFromRecents(0, new Bundle()));
+ () -> mService.mActivityTaskManager.startActivityFromRecents(0, new Bundle()));
assertSecurityException(expectCallable,
- () -> mService.getTaskSnapshot(0, true));
- assertSecurityException(expectCallable, () -> {
- try {
- mService.registerTaskStackListener(null);
- } catch (RemoteException e) {
- // Ignore
- }
- });
- assertSecurityException(expectCallable, () -> {
- try {
- mService.unregisterTaskStackListener(null);
- } catch (RemoteException e) {
- // Ignore
- }
- });
- assertSecurityException(expectCallable, () -> mService.getTaskDescription(0));
- assertSecurityException(expectCallable, () -> mService.cancelTaskWindowTransition(0));
- assertSecurityException(expectCallable, () -> mService.startRecentsActivity(null, null,
+ () -> mService.mActivityTaskManager.getTaskSnapshot(0, true));
+ assertSecurityException(expectCallable,
+ () -> mService.mActivityTaskManager.registerTaskStackListener(null));
+ assertSecurityException(expectCallable,
+ () -> mService.mActivityTaskManager.unregisterTaskStackListener(null));
+ assertSecurityException(expectCallable, () -> mService.mActivityTaskManager.getTaskDescription(0));
+ assertSecurityException(expectCallable, () -> mService.mActivityTaskManager.cancelTaskWindowTransition(0));
+ assertSecurityException(expectCallable, () -> mService.mActivityTaskManager.startRecentsActivity(null, null,
null));
- assertSecurityException(expectCallable, () -> mService.cancelRecentsAnimation(true));
+ assertSecurityException(expectCallable, () -> mService.mActivityTaskManager.cancelRecentsAnimation(true));
assertSecurityException(expectCallable, () -> mService.stopAppSwitches());
assertSecurityException(expectCallable, () -> mService.resumeAppSwitches());
}
diff --git a/services/tests/servicestests/src/com/android/server/am/TaskStackChangedListenerTest.java b/services/tests/servicestests/src/com/android/server/am/TaskStackChangedListenerTest.java
index 0359096..8e87a5f 100644
--- a/services/tests/servicestests/src/com/android/server/am/TaskStackChangedListenerTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/TaskStackChangedListenerTest.java
@@ -24,6 +24,7 @@
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.TaskDescription;
+import android.app.ActivityTaskManager;
import android.app.IActivityManager;
import android.app.ITaskStackListener;
import android.app.Instrumentation.ActivityMonitor;
@@ -68,7 +69,7 @@
@After
public void tearDown() throws Exception {
- mService.unregisterTaskStackListener(mTaskStackListener);
+ ActivityTaskManager.getService().unregisterTaskStackListener(mTaskStackListener);
mTaskStackListener = null;
}
@@ -227,7 +228,7 @@
private void registerTaskStackChangedListener(ITaskStackListener listener) throws Exception {
mTaskStackListener = listener;
- mService.registerTaskStackListener(listener);
+ ActivityTaskManager.getService().registerTaskStackListener(listener);
}
private void waitForCallback(CountDownLatch latch) {
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
index cd39285..2b5b812 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java
@@ -18,6 +18,7 @@
import android.app.ActivityManagerInternal;
import android.app.AlarmManager;
import android.app.IActivityManager;
+import android.app.IActivityTaskManager;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.backup.IBackupManager;
@@ -181,6 +182,11 @@
}
@Override
+ IActivityTaskManager getIActivityTaskManager() {
+ return services.iactivityTaskManager;
+ }
+
+ @Override
ActivityManagerInternal getActivityManagerInternal() {
return services.activityManagerInternal;
}
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index 1acecfc..a23636c 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -3726,7 +3726,7 @@
private void verifyLockTaskState(int userId, String[] packages, int flags) throws Exception {
verify(getServices().iactivityManager).updateLockTaskPackages(userId, packages);
- verify(getServices().iactivityManager).updateLockTaskFeatures(userId, flags);
+ verify(getServices().iactivityTaskManager).updateLockTaskFeatures(userId, flags);
}
private void verifyCanSetLockTask(int uid, int userId, ComponentName who, String[] packages,
@@ -3819,7 +3819,7 @@
// Lock task packages cleared when loading user data and when the user becomes unaffiliated.
verify(getServices().iactivityManager, times(2)).updateLockTaskPackages(
MANAGED_PROFILE_USER_ID, new String[0]);
- verify(getServices().iactivityManager, times(2)).updateLockTaskFeatures(
+ verify(getServices().iactivityTaskManager, times(2)).updateLockTaskFeatures(
MANAGED_PROFILE_USER_ID, DevicePolicyManager.LOCK_TASK_FEATURE_NONE);
// Verify that lock task packages were not cleared for the DO
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java b/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java
index e753df1..4724f1c 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/MockSystemServices.java
@@ -28,6 +28,7 @@
import android.app.ActivityManagerInternal;
import android.app.AlarmManager;
import android.app.IActivityManager;
+import android.app.IActivityTaskManager;
import android.app.NotificationManager;
import android.app.backup.IBackupManager;
import android.app.usage.UsageStatsManagerInternal;
@@ -91,6 +92,7 @@
public final IIpConnectivityMetrics iipConnectivityMetrics;
public final IWindowManager iwindowManager;
public final IActivityManager iactivityManager;
+ public final IActivityTaskManager iactivityTaskManager;
public ActivityManagerInternal activityManagerInternal;
public final IPackageManager ipackageManager;
public final IBackupManager ibackupManager;
@@ -129,6 +131,7 @@
iipConnectivityMetrics = mock(IIpConnectivityMetrics.class);
iwindowManager = mock(IWindowManager.class);
iactivityManager = mock(IActivityManager.class);
+ iactivityTaskManager = mock(IActivityTaskManager.class);
activityManagerInternal = mock(ActivityManagerInternal.class);
ipackageManager = mock(IPackageManager.class);
ibackupManager = mock(IBackupManager.class);
diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskPositionerTests.java b/services/tests/servicestests/src/com/android/server/wm/TaskPositionerTests.java
index 4447b26..dc6bbbf 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TaskPositionerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskPositionerTests.java
@@ -22,6 +22,7 @@
import org.junit.Test;
import org.junit.runner.RunWith;
+import android.app.IActivityTaskManager;
import android.graphics.Rect;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
@@ -75,7 +76,7 @@
mMinVisibleWidth = dipToPixel(MINIMUM_VISIBLE_WIDTH_IN_DP, dm);
mMinVisibleHeight = dipToPixel(MINIMUM_VISIBLE_HEIGHT_IN_DP, dm);
- mPositioner = new TaskPositioner(sWm, Mockito.mock(IActivityManager.class));
+ mPositioner = new TaskPositioner(sWm, Mockito.mock(IActivityTaskManager.class));
mPositioner.register(mDisplayContent);
mWindow = Mockito.spy(createWindow(null, TYPE_BASE_APPLICATION, "window"));
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
index b26efd5..ba94afe 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
@@ -25,7 +25,9 @@
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
import android.app.ActivityOptions;
+import android.app.ActivityTaskManager;
import android.app.IActivityManager;
+import android.app.IActivityTaskManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
@@ -70,6 +72,7 @@
final int mUser;
final ComponentName mComponent;
final IActivityManager mAm;
+ final IActivityTaskManager mAtm;
final VoiceInteractionServiceInfo mInfo;
final ComponentName mSessionComponentName;
final IWindowManager mIWindowManager;
@@ -125,6 +128,7 @@
mUser = userHandle;
mComponent = service;
mAm = ActivityManager.getService();
+ mAtm = ActivityTaskManager.getService();
VoiceInteractionServiceInfo info;
try {
info = new VoiceInteractionServiceInfo(context.getPackageManager(), service, mUser);
@@ -205,7 +209,7 @@
intent = new Intent(intent);
intent.addCategory(Intent.CATEGORY_VOICE);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
- return mAm.startVoiceActivity(mComponent.getPackageName(), callingPid, callingUid,
+ return mAtm.startVoiceActivity(mComponent.getPackageName(), callingPid, callingUid,
intent, resolvedType, mActiveSession.mSession, mActiveSession.mInteractor,
0, null, null, mUser);
} catch (RemoteException e) {
@@ -228,7 +232,7 @@
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
final ActivityOptions options = ActivityOptions.makeBasic();
options.setLaunchActivityType(ACTIVITY_TYPE_ASSISTANT);
- return mAm.startAssistantActivity(mComponent.getPackageName(), callingPid, callingUid,
+ return mAtm.startAssistantActivity(mComponent.getPackageName(), callingPid, callingUid,
intent, resolvedType, options.toBundle(), mUser);
} catch (RemoteException e) {
throw new IllegalStateException("Unexpected remote error", e);
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
index e0d9c73..457bfcd 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
@@ -27,6 +27,7 @@
import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
import android.app.ActivityManager;
+import android.app.ActivityTaskManager;
import android.app.AppOpsManager;
import android.app.IActivityManager;
import android.app.assist.AssistContent;
@@ -359,7 +360,7 @@
}
if (mSession != null) {
try {
- mAm.finishVoiceTask(mSession);
+ ActivityTaskManager.getService().finishVoiceTask(mSession);
} catch (RemoteException e) {
}
}
@@ -387,7 +388,7 @@
}
if (finishTask && mSession != null) {
try {
- mAm.finishVoiceTask(mSession);
+ ActivityTaskManager.getService().finishVoiceTask(mSession);
} catch (RemoteException e) {
}
}