summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author TreeHugger Robot <treehugger-gerrit@google.com> 2018-07-29 09:29:35 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2018-07-29 09:29:35 +0000
commitfab85f0fc33da068502c4debc2933f61fcd905fc (patch)
tree6b0cd75649eaaa9478e1a9b89f97777beee60de5
parenta1b12c82a1b466967ef285f53ddc6850243e4d84 (diff)
parent008163e777d5ed3779195129b72b6947f7086847 (diff)
Merge changes Ide697f9f,Ia76c5741
* changes: Moved AppWarnings handling to ActivityTaskManagerService (15/n) Moved input time out handling to ActivityTaskManagerService (14/n)
-rw-r--r--core/java/android/app/ActivityManagerInternal.java3
-rw-r--r--core/java/android/app/IActivityManager.aidl1
-rw-r--r--services/core/java/com/android/server/am/ActiveServices.java2
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java292
-rw-r--r--services/core/java/com/android/server/am/ActivityRecord.java18
-rw-r--r--services/core/java/com/android/server/am/ActivityStack.java3
-rw-r--r--services/core/java/com/android/server/am/ActivityStackSupervisor.java7
-rw-r--r--services/core/java/com/android/server/am/ActivityStartInterceptor.java4
-rw-r--r--services/core/java/com/android/server/am/ActivityStarter.java10
-rw-r--r--services/core/java/com/android/server/am/ActivityTaskManagerService.java160
-rw-r--r--services/core/java/com/android/server/am/AppErrors.java2
-rw-r--r--services/core/java/com/android/server/am/AppWarnings.java25
-rw-r--r--services/core/java/com/android/server/am/BroadcastQueue.java2
-rw-r--r--services/core/java/com/android/server/am/CompatModeDialog.java90
-rw-r--r--services/core/java/com/android/server/am/ProcessRecord.java42
-rw-r--r--services/core/java/com/android/server/am/RecentTasks.java2
-rw-r--r--services/core/java/com/android/server/am/WindowProcessController.java30
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java7
-rw-r--r--services/core/java/com/android/server/wm/InputManagerCallback.java19
-rw-r--r--services/tests/servicestests/src/com/android/server/am/ActivityStartInterceptorTest.java4
-rw-r--r--services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java45
-rw-r--r--services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java3
22 files changed, 409 insertions, 362 deletions
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index c8959788cf50..2baae92bc6a8 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -228,4 +228,7 @@ public abstract class ActivityManagerInternal {
public abstract boolean isCurrentProfile(int userId);
public abstract boolean hasStartedUserState(int userId);
public abstract void finishUserSwitch(Object uss);
+
+ /** Schedule the execution of all pending app GCs. */
+ public abstract void scheduleAppGcs();
}
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 285f83b9457b..16360b3bf5a8 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -325,7 +325,6 @@ interface IActivityManager {
*/
void requestWifiBugReport(in String shareTitle, in String shareDescription);
- long inputDispatchingTimedOut(int pid, boolean aboveSystem, in String reason);
void clearPendingBackup();
Intent getIntentForIntentSender(in IIntentSender sender);
// This is not public because you need to be very careful in how you
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 29937ab42d15..5bf6892adb23 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -3658,7 +3658,7 @@ public final class ActiveServices {
}
app = r.app;
- if (app != null && app.debugging) {
+ if (app != null && app.isDebugging()) {
// The app's being debugged; let it ride
return;
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 594b39135ea6..aa0315ab3214 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -463,12 +463,6 @@ public class ActivityManagerService extends IActivityManager.Stub
static final int BROADCAST_FG_TIMEOUT = 10*1000;
static final int BROADCAST_BG_TIMEOUT = 60*1000;
- // How long we wait until we timeout on key dispatching.
- static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
-
- // How long we wait until we timeout on key dispatching during instrumentation.
- static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
-
// Disable hidden API checks for the newly started instrumentation.
// Must be kept in sync with Am.
private static final int INSTRUMENTATION_FLAG_DISABLE_HIDDEN_API_CHECKS = 1 << 0;
@@ -574,8 +568,6 @@ public class ActivityManagerService extends IActivityManager.Stub
final AppErrors mAppErrors;
- final AppWarnings mAppWarnings;
-
/**
* Dump of the activity state at the time of the last ANR. Cleared after
* {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS}
@@ -695,10 +687,42 @@ public class ActivityManagerService extends IActivityManager.Stub
* All of the processes we currently have running organized by pid.
* The keys are the pid running the application.
*
- * <p>NOTE: This object is protected by its own lock, NOT the global
- * activity manager lock!
+ * <p>NOTE: This object is protected by its own lock, NOT the global activity manager lock!
*/
- final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
+ final PidMap mPidsSelfLocked = new PidMap();
+ final class PidMap {
+ private final SparseArray<ProcessRecord> mPidMap = new SparseArray<>();
+
+ void put(int key, ProcessRecord value) {
+ mPidMap.put(key, value);
+ mAtmInternal.onProcessMapped(key, value.getWindowProcessController());
+ }
+
+ void remove(int pid) {
+ mPidMap.remove(pid);
+ mAtmInternal.onProcessUnMapped(pid);
+ }
+
+ ProcessRecord get(int pid) {
+ return mPidMap.get(pid);
+ }
+
+ int size() {
+ return mPidMap.size();
+ }
+
+ ProcessRecord valueAt(int index) {
+ return mPidMap.valueAt(index);
+ }
+
+ int keyAt(int index) {
+ return mPidMap.keyAt(index);
+ }
+
+ int indexOfKey(int key) {
+ return mPidMap.indexOfKey(key);
+ }
+ }
/**
* All of the processes that have been forced to be important. The key
@@ -1425,7 +1449,6 @@ public class ActivityManagerService extends IActivityManager.Stub
static final int CHECK_EXCESSIVE_POWER_USE_MSG = 27;
static final int CLEAR_DNS_CACHE_MSG = 28;
static final int UPDATE_HTTP_PROXY_MSG = 29;
- static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
static final int REPORT_MEM_USAGE_MSG = 33;
@@ -1456,7 +1479,6 @@ public class ActivityManagerService extends IActivityManager.Stub
static ServiceThread sKillThread = null;
static KillHandler sKillHandler = null;
- CompatModeDialog mCompatModeDialog;
long mLastMemUsageReportTime = 0;
/**
@@ -1587,34 +1609,6 @@ public class ActivityManagerService extends IActivityManager.Stub
}
}
} break;
- case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
- synchronized (ActivityManagerService.this) {
- ActivityRecord ar = (ActivityRecord) msg.obj;
- if (mCompatModeDialog != null) {
- if (mCompatModeDialog.mAppInfo.packageName.equals(
- ar.info.applicationInfo.packageName)) {
- return;
- }
- mCompatModeDialog.dismiss();
- mCompatModeDialog = null;
- }
- if (ar != null && false) {
- if (mCompatModePackages.getPackageAskCompatModeLocked(
- ar.packageName)) {
- int mode = mCompatModePackages.computeCompatModeLocked(
- ar.info.applicationInfo);
- if (mode == ActivityManager.COMPAT_MODE_DISABLED
- || mode == ActivityManager.COMPAT_MODE_ENABLED) {
- mCompatModeDialog = new CompatModeDialog(
- ActivityManagerService.this, mUiContext,
- ar.info.applicationInfo);
- mCompatModeDialog.show();
- }
- }
- }
- }
- break;
- }
case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
dispatchProcessesChanged();
break;
@@ -2433,7 +2427,6 @@ public class ActivityManagerService extends IActivityManager.Stub
mUiContext = null;
GL_ES_VERSION = 0;
mAppErrors = null;
- mAppWarnings = null;
mAppOpsService = mInjector.getAppOpsService(null, null);
mBatteryStatsService = null;
mCompatModePackages = null;
@@ -2500,8 +2493,6 @@ public class ActivityManagerService extends IActivityManager.Stub
final File systemDir = SystemServiceManager.ensureSystemDir();
- mAppWarnings = new AppWarnings(this, mUiContext, mHandler, mUiHandler, systemDir);
-
// TODO: Move creation of battery stats service outside of activity manager service.
mBatteryStatsService = new BatteryStatsService(systemContext, systemDir, mHandler);
mBatteryStatsService.getActiveStatistics().readLocked();
@@ -2891,28 +2882,6 @@ public class ActivityManagerService extends IActivityManager.Stub
mActivityTaskManager.unregisterTaskStackListener(listener);
}
- final void showAskCompatModeDialogLocked(ActivityRecord r) {
- Message msg = Message.obtain();
- msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
- msg.obj = r.getTask().askedCompatMode ? null : r;
- mUiHandler.sendMessage(msg);
- }
-
- final AppWarnings getAppWarningsLocked() {
- return mAppWarnings;
- }
-
- /**
- * Shows app warning dialogs, if necessary.
- *
- * @param r activity record for which the warnings may be displayed
- */
- final void showAppWarningsIfNeededLocked(ActivityRecord r) {
- mAppWarnings.showUnsupportedCompileSdkDialogIfNeeded(r);
- mAppWarnings.showUnsupportedDisplaySizeDialogIfNeeded(r);
- mAppWarnings.showDeprecatedTargetDialogIfNeeded(r);
- }
-
private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
String what, Object obj, ProcessRecord srcApp) {
app.lastActivityTime = now;
@@ -3635,8 +3604,8 @@ public class ActivityManagerService extends IActivityManager.Stub
app.pendingStart = false;
return;
}
- app.usingWrapper = invokeWith != null
- || SystemProperties.get("wrap." + app.processName) != null;
+ app.setUsingWrapper(invokeWith != null
+ || SystemProperties.get("wrap." + app.processName) != null);
mPendingStarts.put(startSeq, app);
}
final ProcessStartResult startResult = startProcess(app.hostingType, entryPoint,
@@ -3732,7 +3701,7 @@ public class ActivityManagerService extends IActivityManager.Stub
// Indicates that this process start has been taken care of.
if (mPendingStarts.get(expectedStartSeq) == null) {
if (pending.pid == startResult.pid) {
- pending.usingWrapper = startResult.usingWrapper;
+ pending.setUsingWrapper(startResult.usingWrapper);
// TODO: Update already existing clients of usingWrapper
}
return false;
@@ -3795,7 +3764,7 @@ public class ActivityManagerService extends IActivityManager.Stub
}
reportUidInfoMessageLocked(TAG, buf.toString(), app.startUid);
app.setPid(pid);
- app.usingWrapper = usingWrapper;
+ app.setUsingWrapper(usingWrapper);
app.pendingStart = false;
checkTime(app.startTime, "startProcess: starting to update pids map");
ProcessRecord oldApp;
@@ -3880,7 +3849,7 @@ public class ActivityManagerService extends IActivityManager.Stub
aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
ProcessRecord app = getProcessRecordLocked(aInfo.processName,
aInfo.applicationInfo.uid, true);
- if (app == null || app.instr == null) {
+ if (app == null || app.getActiveInstrumentation() == null) {
intent.setFlags(intent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
// For ANR debugging to verify if the user activity is the one that actually
@@ -4400,9 +4369,9 @@ public class ActivityManagerService extends IActivityManager.Stub
app.clearRecentTasks();
app.clearActivities();
- if (app.instr != null) {
+ if (app.getActiveInstrumentation() != null) {
Slog.w(TAG, "Crash of app " + app.processName
- + " running instrumentation " + app.instr.mClass);
+ + " running instrumentation " + app.getActiveInstrumentation().mClass);
Bundle info = new Bundle();
info.putString("shortMsg", "Process crashed.");
finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
@@ -4556,7 +4525,7 @@ public class ActivityManagerService extends IActivityManager.Stub
// Clean up already done if the process has been re-started.
if (app.pid == pid && app.thread != null &&
app.thread.asBinder() == thread.asBinder()) {
- boolean doLowMem = app.instr == null;
+ boolean doLowMem = app.getActiveInstrumentation() == null;
boolean doOomAdj = doLowMem;
if (!app.killedByAm) {
reportUidInfoMessageLocked(TAG,
@@ -5885,7 +5854,7 @@ public class ActivityManagerService extends IActivityManager.Stub
if (app == null && startSeq > 0) {
final ProcessRecord pending = mPendingStarts.get(startSeq);
if (pending != null && pending.startUid == callingUid
- && handleProcessStartedLocked(pending, pid, pending.usingWrapper,
+ && handleProcessStartedLocked(pending, pid, pending.isUsingWrapper(),
startSeq, true)) {
app = pending;
}
@@ -5939,7 +5908,7 @@ public class ActivityManagerService extends IActivityManager.Stub
app.forcingToImportant = null;
updateProcessForegroundLocked(app, false, false);
app.hasShownUi = false;
- app.debugging = false;
+ app.setDebugging(false);
app.cached = false;
app.killedByAm = false;
app.killed = false;
@@ -5976,7 +5945,7 @@ public class ActivityManagerService extends IActivityManager.Stub
testMode = mWaitForDebugger
? ApplicationThreadConstants.DEBUG_WAIT
: ApplicationThreadConstants.DEBUG_ON;
- app.debugging = true;
+ app.setDebugging(true);
if (mDebugTransient) {
mDebugApp = mOrigDebugApp;
mWaitForDebugger = mOrigWaitForDebugger;
@@ -5998,13 +5967,15 @@ public class ActivityManagerService extends IActivityManager.Stub
|| (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
}
- if (app.instr != null) {
- notifyPackageUse(app.instr.mClass.getPackageName(),
+ final ActiveInstrumentation instr = app.getActiveInstrumentation();
+
+ if (instr != null) {
+ notifyPackageUse(instr.mClass.getPackageName(),
PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
}
if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
+ processName + " with config " + getGlobalConfiguration());
- ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
+ ApplicationInfo appInfo = instr != null ? instr.mTargetInfo : app.info;
app.compat = compatibilityInfoForPackageLocked(appInfo);
ProfilerInfo profilerInfo = null;
@@ -6021,8 +5992,8 @@ public class ActivityManagerService extends IActivityManager.Stub
preBindAgent = mProfilerInfo.agent;
}
}
- } else if (app.instr != null && app.instr.mProfileFile != null) {
- profilerInfo = new ProfilerInfo(app.instr.mProfileFile, null, 0, false, false,
+ } else if (instr != null && instr.mProfileFile != null) {
+ profilerInfo = new ProfilerInfo(instr.mProfileFile, null, 0, false, false,
null, false);
}
if (mAppAgentMap != null && mAppAgentMap.containsKey(processName)) {
@@ -6059,21 +6030,22 @@ public class ActivityManagerService extends IActivityManager.Stub
// currently active instrumentation. (Note we do this AFTER all of the profiling
// stuff above because profiling can currently happen only in the primary
// instrumentation process.)
- if (mActiveInstrumentation.size() > 0 && app.instr == null) {
- for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
+ if (mActiveInstrumentation.size() > 0 && instr == null) {
+ for (int i = mActiveInstrumentation.size() - 1;
+ i >= 0 && app.getActiveInstrumentation() == null; i--) {
ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
if (aInstr.mTargetProcesses.length == 0) {
// This is the wildcard mode, where every process brought up for
// the target instrumentation should be included.
if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
- app.instr = aInstr;
+ app.setActiveInstrumentation(aInstr);
aInstr.mRunningProcesses.add(app);
}
} else {
for (String proc : aInstr.mTargetProcesses) {
if (proc.equals(app.processName)) {
- app.instr = aInstr;
+ app.setActiveInstrumentation(aInstr);
aInstr.mRunningProcesses.add(app);
break;
}
@@ -6103,16 +6075,17 @@ public class ActivityManagerService extends IActivityManager.Stub
checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
mStackSupervisor.getActivityMetricsLogger().notifyBindApplication(app);
+ final ActiveInstrumentation instr2 = app.getActiveInstrumentation();
if (app.isolatedEntryPoint != null) {
// This is an isolated process which should just call an entry point instead of
// being bound to an application.
thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs);
- } else if (app.instr != null) {
+ } else if (instr2 != null) {
thread.bindApplication(processName, appInfo, providers,
- app.instr.mClass,
- profilerInfo, app.instr.mArguments,
- app.instr.mWatcher,
- app.instr.mUiAutomationConnection, testMode,
+ instr2.mClass,
+ profilerInfo, instr2.mArguments,
+ instr2.mWatcher,
+ instr2.mUiAutomationConnection, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.isPersistent(),
new Configuration(getGlobalConfiguration()), app.compat,
@@ -9257,7 +9230,8 @@ public class ActivityManagerService extends IActivityManager.Stub
if (proc == null) {
throw new SecurityException("Unknown process: " + callingPid);
}
- if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
+ if (proc.getActiveInstrumentation() == null
+ || proc.getActiveInstrumentation().mUiAutomationConnection == null) {
throw new SecurityException("Only an instrumentation process "
+ "with a UiAutomation can call setUserIsMonkey");
}
@@ -9380,89 +9354,6 @@ public class ActivityManagerService extends IActivityManager.Stub
ActivityManager.BUGREPORT_OPTION_WIFI);
}
-
- public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
- if (r == null || !r.hasProcess()) {
- return KEY_DISPATCHING_TIMEOUT;
- }
- return getInputDispatchingTimeoutLocked((ProcessRecord) r.app.mOwner);
- }
-
- public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
- if (r != null && (r.instr != null || r.usingWrapper)) {
- return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
- }
- return KEY_DISPATCHING_TIMEOUT;
- }
-
- @Override
- public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
- if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException("Requires permission "
- + android.Manifest.permission.FILTER_EVENTS);
- }
- ProcessRecord proc;
- long timeout;
- synchronized (this) {
- synchronized (mPidsSelfLocked) {
- proc = mPidsSelfLocked.get(pid);
- }
- timeout = getInputDispatchingTimeoutLocked(proc);
- }
-
- if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
- return -1;
- }
-
- return timeout;
- }
-
- /**
- * Handle input dispatching timeouts.
- * Returns whether input dispatching should be aborted or not.
- */
- public boolean inputDispatchingTimedOut(final ProcessRecord proc,
- final ActivityRecord activity, final ActivityRecord parent,
- final boolean aboveSystem, String reason) {
- if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException("Requires permission "
- + android.Manifest.permission.FILTER_EVENTS);
- }
-
- final String annotation;
- if (reason == null) {
- annotation = "Input dispatching timed out";
- } else {
- annotation = "Input dispatching timed out (" + reason + ")";
- }
-
- if (proc != null) {
- synchronized (this) {
- if (proc.debugging) {
- return false;
- }
-
- if (proc.instr != null) {
- Bundle info = new Bundle();
- info.putString("shortMsg", "keyDispatchingTimedOut");
- info.putString("longMsg", annotation);
- finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
- return true;
- }
- }
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
- }
- });
- }
-
- return true;
- }
-
public void registerProcessObserver(IProcessObserver observer) {
enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
"registerProcessObserver()");
@@ -16425,7 +16316,7 @@ public class ActivityManagerService extends IActivityManager.Stub
mActivityTaskManager.getRecentTasks().removeTasksByPackageName(ssp, userId);
mServices.forceStopPackageLocked(ssp, userId);
- mAppWarnings.onPackageUninstalled(ssp);
+ mAtmInternal.onPackageUninstalled(ssp);
mCompatModePackages.handlePackageUninstalledLocked(ssp);
mBatteryStatsService.notePackageUninstalled(ssp);
}
@@ -16506,7 +16397,7 @@ public class ActivityManagerService extends IActivityManager.Stub
String ssp;
if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
mCompatModePackages.handlePackageDataClearedLocked(ssp);
- mAppWarnings.onPackageDataCleared(ssp);
+ mAtmInternal.onPackageDataCleared(ssp);
}
break;
}
@@ -17137,7 +17028,7 @@ public class ActivityManagerService extends IActivityManager.Stub
ProcessRecord app = addAppLocked(ai, defProcess, false, disableHiddenApiChecks,
abiOverride);
- app.instr = activeInstr;
+ app.setActiveInstrumentation(activeInstr);
activeInstr.mFinished = false;
activeInstr.mRunningProcesses.add(app);
if (!mActiveInstrumentation.contains(activeInstr)) {
@@ -17170,16 +17061,17 @@ public class ActivityManagerService extends IActivityManager.Stub
}
void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
- if (app.instr == null) {
+ final ActiveInstrumentation instr = app.getActiveInstrumentation();
+ if (instr == null) {
Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
return;
}
- if (!app.instr.mFinished && results != null) {
- if (app.instr.mCurResults == null) {
- app.instr.mCurResults = new Bundle(results);
+ if (!instr.mFinished && results != null) {
+ if (instr.mCurResults == null) {
+ instr.mCurResults = new Bundle(results);
} else {
- app.instr.mCurResults.putAll(results);
+ instr.mCurResults.putAll(results);
}
}
}
@@ -17205,37 +17097,38 @@ public class ActivityManagerService extends IActivityManager.Stub
@GuardedBy("this")
void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
- if (app.instr == null) {
+ final ActiveInstrumentation instr = app.getActiveInstrumentation();
+ if (instr == null) {
Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
return;
}
- if (!app.instr.mFinished) {
- if (app.instr.mWatcher != null) {
- Bundle finalResults = app.instr.mCurResults;
+ if (!instr.mFinished) {
+ if (instr.mWatcher != null) {
+ Bundle finalResults = instr.mCurResults;
if (finalResults != null) {
- if (app.instr.mCurResults != null && results != null) {
+ if (instr.mCurResults != null && results != null) {
finalResults.putAll(results);
}
} else {
finalResults = results;
}
- mInstrumentationReporter.reportFinished(app.instr.mWatcher,
- app.instr.mClass, resultCode, finalResults);
+ mInstrumentationReporter.reportFinished(instr.mWatcher,
+ instr.mClass, resultCode, finalResults);
}
// Can't call out of the system process with a lock held, so post a message.
- if (app.instr.mUiAutomationConnection != null) {
+ if (instr.mUiAutomationConnection != null) {
mAppOpsService.setAppOpsServiceDelegate(null);
getPackageManagerInternalLocked().setCheckPermissionDelegate(null);
mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
- app.instr.mUiAutomationConnection).sendToTarget();
+ instr.mUiAutomationConnection).sendToTarget();
}
- app.instr.mFinished = true;
+ instr.mFinished = true;
}
- app.instr.removeProcess(app);
- app.instr = null;
+ instr.removeProcess(app);
+ app.setActiveInstrumentation(null);
forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
"finished inst");
@@ -17709,7 +17602,7 @@ public class ActivityManagerService extends IActivityManager.Stub
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making running remote anim: " + app);
}
- } else if (app.instr != null) {
+ } else if (app.getActiveInstrumentation() != null) {
// Don't want to kill running instrumentation.
adj = ProcessList.FOREGROUND_APP_ADJ;
schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
@@ -21208,6 +21101,13 @@ public class ActivityManagerService extends IActivityManager.Stub
return ActivityManagerService.this.getHomeIntent();
}
}
+
+ @Override
+ public void scheduleAppGcs() {
+ synchronized (ActivityManagerService.this) {
+ ActivityManagerService.this.scheduleAppGcsLocked();
+ }
+ }
}
/**
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 19ea9554e720..bd621edeeedd 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -1036,7 +1036,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
(info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0, info.configChanges,
task.voiceSession != null, mLaunchTaskBehind, isAlwaysFocusable(),
appInfo.targetSdkVersion, mRotationAnimationHint,
- ActivityManagerService.getInputDispatchingTimeoutLocked(this) * 1000000L);
+ ActivityTaskManagerService.getInputDispatchingTimeoutLocked(this) * 1000000L);
task.addActivityToTop(this);
@@ -2134,7 +2134,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
mStackSupervisor.processStoppingActivitiesLocked(null /* idleActivity */,
false /* remove */, true /* processPausingActivities */);
}
- service.mAm.scheduleAppGcsLocked();
+ service.scheduleAppGcsLocked();
}
}
}
@@ -2159,13 +2159,11 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
!hasProcess() || app.getPid() == windowPid || windowPid == -1;
}
if (windowFromSameProcessAsActivity) {
- return service.mAm.inputDispatchingTimedOut(
- (ProcessRecord) anrApp.mOwner, anrActivity, this, false, reason);
+ return service.inputDispatchingTimedOut(anrApp, anrActivity, this, false, reason);
} else {
// In this case another process added windows using this activity token. So, we call the
// generic service input dispatch timed out method so that the right process is blamed.
- return service.mAm.inputDispatchingTimedOut(
- windowPid, false /* aboveSystem */, reason) < 0;
+ return service.inputDispatchingTimedOut(windowPid, false /* aboveSystem */, reason) < 0;
}
}
@@ -2819,10 +2817,12 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
}
results = null;
newIntents = null;
- service.mAm.getAppWarningsLocked().onResumeActivity(this);
- service.mAm.showAskCompatModeDialogLocked(this);
+ service.getAppWarningsLocked().onResumeActivity(this);
} else {
- service.mAm.mHandler.removeMessages(PAUSE_TIMEOUT_MSG, this);
+ final ActivityStack stack = getStack();
+ if (stack != null) {
+ stack.mHandler.removeMessages(PAUSE_TIMEOUT_MSG, this);
+ }
setState(PAUSED, "relaunchActivityLocked");
}
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 058c714148a4..cbce3f4798b8 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -2722,8 +2722,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
next.shortComponentName);
next.sleeping = false;
- mService.mAm.getAppWarningsLocked().onResumeActivity(next);
- mService.mAm.showAskCompatModeDialogLocked(next);
+ mService.getAppWarningsLocked().onResumeActivity(next);
next.app.setPendingUiCleanAndForceProcessStateUpTo(mService.mTopProcessState);
next.clearOptionsLocked();
transaction.setLifecycleStateRequest(
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index a7325754f178..002f718a3905 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -1400,7 +1400,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
// (e.g. AMS.startActivityAsUser).
final long token = Binder.clearCallingIdentity();
try {
- return mService.mAm.getPackageManagerInternalLocked().resolveIntent(
+ return mService.getPackageManagerInternalLocked().resolveIntent(
intent, resolvedType, modifiedFlags, userId, true, filterCallingUid);
} finally {
Binder.restoreCallingIdentity(token);
@@ -1523,8 +1523,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
PackageManager.NOTIFY_PACKAGE_USE_ACTIVITY);
r.sleeping = false;
r.forceNewConfig = false;
- mService.mAm.getAppWarningsLocked().onStartActivity(r);
- mService.mAm.showAskCompatModeDialogLocked(r);
+ mService.getAppWarningsLocked().onStartActivity(r);
r.compat = mService.mAm.compatibilityInfoForPackageLocked(r.info.applicationInfo);
ProfilerInfo profilerInfo = null;
if (mService.mAm.mProfileApp != null && mService.mAm.mProfileApp.equals(app.processName)) {
@@ -2109,7 +2108,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
if (allResumedActivitiesIdle()) {
if (r != null) {
- mService.mAm.scheduleAppGcsLocked();
+ mService.scheduleAppGcsLocked();
}
if (mLaunchingActivity.isHeld()) {
diff --git a/services/core/java/com/android/server/am/ActivityStartInterceptor.java b/services/core/java/com/android/server/am/ActivityStartInterceptor.java
index ca12716e7199..177e2f563a4b 100644
--- a/services/core/java/com/android/server/am/ActivityStartInterceptor.java
+++ b/services/core/java/com/android/server/am/ActivityStartInterceptor.java
@@ -237,7 +237,7 @@ class ActivityStartInterceptor {
(mAInfo.applicationInfo.flags & FLAG_SUSPENDED) == 0) {
return false;
}
- final PackageManagerInternal pmi = mService.mAm.getPackageManagerInternalLocked();
+ final PackageManagerInternal pmi = mService.getPackageManagerInternalLocked();
if (pmi == null) {
return false;
}
@@ -318,7 +318,7 @@ class ActivityStartInterceptor {
private boolean interceptHarmfulAppIfNeeded() {
CharSequence harmfulAppWarning;
try {
- harmfulAppWarning = mService.mAm.getPackageManager()
+ harmfulAppWarning = mService.getPackageManager()
.getHarmfulAppWarning(mAInfo.packageName, mUserId);
} catch (RemoteException ex) {
return false;
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index 8be5adab1713..0a1b26c968b4 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -672,7 +672,7 @@ class ActivityStarter {
&& sourceRecord.info.applicationInfo.uid != aInfo.applicationInfo.uid) {
try {
intent.addCategory(Intent.CATEGORY_VOICE);
- if (!mService.mAm.getPackageManager().activitySupportsIntent(
+ if (!mService.getPackageManager().activitySupportsIntent(
intent.getComponent(), intent, resolvedType)) {
Slog.w(TAG,
"Activity being started in current voice task does not support voice: "
@@ -690,7 +690,7 @@ class ActivityStarter {
// If the caller is starting a new voice session, just make sure the target
// is actually allowing it to run this way.
try {
- if (!mService.mAm.getPackageManager().activitySupportsIntent(intent.getComponent(),
+ if (!mService.getPackageManager().activitySupportsIntent(intent.getComponent(),
intent, resolvedType)) {
Slog.w(TAG,
"Activity being started in new voice task does not support: "
@@ -772,7 +772,7 @@ class ActivityStarter {
// launch the review activity and pass a pending intent to start the activity
// we are to launching now after the review is completed.
if (aInfo != null) {
- if (mService.mAm.getPackageManagerInternalLocked().isPermissionsReviewRequired(
+ if (mService.getPackageManagerInternalLocked().isPermissionsReviewRequired(
aInfo.packageName, userId)) {
IIntentSender target = mService.mAm.getIntentSenderLocked(
ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage,
@@ -870,7 +870,7 @@ class ActivityStarter {
String resolvedType, int userId) {
if (auxiliaryResponse != null && auxiliaryResponse.needsPhaseTwo) {
// request phase two resolution
- mService.mAm.getPackageManagerInternalLocked().requestInstantAppResolutionPhaseTwo(
+ mService.getPackageManagerInternalLocked().requestInstantAppResolutionPhaseTwo(
auxiliaryResponse, originalIntent, resolvedType, callingPackage,
verificationBundle, userId);
}
@@ -970,7 +970,7 @@ class ActivityStarter {
&& !(Intent.ACTION_VIEW.equals(intent.getAction()) && intent.getData() == null)
&& !Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE.equals(intent.getAction())
&& !Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE.equals(intent.getAction())
- && mService.mAm.getPackageManagerInternalLocked()
+ && mService.getPackageManagerInternalLocked()
.isInstantAppInstallerComponent(intent.getComponent())) {
// intercept intents targeted directly to the ephemeral installer the
// ephemeral installer should never be started with a raw Intent; instead
diff --git a/services/core/java/com/android/server/am/ActivityTaskManagerService.java b/services/core/java/com/android/server/am/ActivityTaskManagerService.java
index ab1ba6cce2f5..91f2b5f6f00c 100644
--- a/services/core/java/com/android/server/am/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityTaskManagerService.java
@@ -19,6 +19,7 @@ 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.FILTER_EVENTS;
import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
import static android.Manifest.permission.READ_FRAME_BUFFER;
@@ -36,15 +37,12 @@ import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_CONTE
import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_DATA;
import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_RECEIVER_EXTRAS;
import static com.android.server.wm.ActivityTaskManagerInternal.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.AppOpsManager.OP_NONE;
-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;
@@ -74,7 +72,6 @@ import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATI
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_OOM_ADJ;
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_TASKS;
@@ -122,6 +119,8 @@ import android.app.ActivityThread;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
+import android.content.pm.IPackageManager;
+import android.content.pm.PackageManagerInternal;
import android.database.ContentObserver;
import android.os.IUserManager;
import android.os.PowerManager;
@@ -131,9 +130,9 @@ import android.os.UserManager;
import android.os.WorkSource;
import android.view.WindowManager;
import com.android.internal.R;
-import com.android.internal.annotations.GuardedBy;
import com.android.internal.app.IAppOpsService;
import com.android.server.AppOpsService;
+import com.android.server.SystemServiceManager;
import com.android.server.pm.UserManagerService;
import com.android.server.uri.UriGrantsManagerInternal;
import com.android.server.wm.ActivityTaskManagerInternal;
@@ -181,7 +180,6 @@ import android.os.LocaleList;
import android.os.Looper;
import android.os.Message;
import android.os.PersistableBundle;
-import android.os.Process;
import android.os.RemoteException;
import android.os.StrictMode;
import android.os.SystemClock;
@@ -250,6 +248,11 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
+ // How long we wait until we timeout on key dispatching.
+ private static final int KEY_DISPATCHING_TIMEOUT_MS = 5 * 1000;
+ // How long we wait until we timeout on key dispatching during instrumentation.
+ private static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS = 60 * 1000;
+
Context mContext;
/**
* This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
@@ -261,6 +264,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
ActivityManagerService mAm;
ActivityManagerInternal mAmInternal;
UriGrantsManagerInternal mUgmInternal;
+ private PackageManagerInternal mPmInternal;
/* Global service lock used by the package the owns this service. */
Object mGlobalLock;
ActivityStackSupervisor mStackSupervisor;
@@ -269,6 +273,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
private AppOpsService mAppOpsService;
/** All processes currently running that might have a window organized by name. */
final ProcessMap<WindowProcessController> mProcessNames = new ProcessMap<>();
+ /** All processes we currently have running mapped by pid */
+ final SparseArray<WindowProcessController> mPidMap = new SparseArray<>();
/** This is the process holding what we currently consider to be the "home" activity. */
WindowProcessController mHomeProcess;
/**
@@ -466,6 +472,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
/** If non-null, we are tracking the time the user spends in the currently focused app. */
AppTimeTracker mCurAppTimeTracker;
+ private AppWarnings mAppWarnings;
+
private FontScaleSettingObserver mFontScaleSettingObserver;
private final class FontScaleSettingObserver extends ContentObserver {
@@ -595,6 +603,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
mGlobalLock = mAm;
mH = new H(mAm.mHandlerThread.getLooper());
mUiHandler = new UiHandler();
+ mAppWarnings = new AppWarnings(
+ this, mUiContext, mH, mUiHandler, SystemServiceManager.ensureSystemDir());
mTempConfig.setToDefaults();
mTempConfig.setLocales(LocaleList.getDefault());
@@ -4008,7 +4018,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
synchronized (mGlobalLock) {
final long origId = Binder.clearCallingIdentity();
try {
- mAm.mAppWarnings.alwaysShowUnsupportedCompileSdkWarning(activity);
+ mAppWarnings.alwaysShowUnsupportedCompileSdkWarning(activity);
} finally {
Binder.restoreCallingIdentity(origId);
}
@@ -4493,7 +4503,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
if (isDensityChange && displayId == DEFAULT_DISPLAY) {
- mAm.mAppWarnings.onDensityChanged();
+ mAppWarnings.onDensityChanged();
mAm.killAllBackgroundProcessesExcept(N,
ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
@@ -4540,6 +4550,80 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
&& mAmInternal.getCurrentUser().isDemo());
}
+ static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
+ if (r == null || !r.hasProcess()) {
+ return KEY_DISPATCHING_TIMEOUT_MS;
+ }
+ return getInputDispatchingTimeoutLocked(r.app);
+ }
+
+ private static long getInputDispatchingTimeoutLocked(WindowProcessController r) {
+ if (r != null && (r.isInstrumenting() || r.isUsingWrapper())) {
+ return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS;
+ }
+ return KEY_DISPATCHING_TIMEOUT_MS;
+ }
+
+ long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
+ if (checkCallingPermission(FILTER_EVENTS) != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires permission " + FILTER_EVENTS);
+ }
+ WindowProcessController proc;
+ long timeout;
+ synchronized (mGlobalLock) {
+ proc = mPidMap.get(pid);
+ timeout = getInputDispatchingTimeoutLocked(proc);
+ }
+
+ if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
+ return -1;
+ }
+
+ return timeout;
+ }
+
+ /**
+ * Handle input dispatching timeouts.
+ * Returns whether input dispatching should be aborted or not.
+ */
+ boolean inputDispatchingTimedOut(final WindowProcessController proc,
+ final ActivityRecord activity, final ActivityRecord parent,
+ final boolean aboveSystem, String reason) {
+ if (checkCallingPermission(FILTER_EVENTS) != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires permission " + FILTER_EVENTS);
+ }
+
+ final String annotation;
+ if (reason == null) {
+ annotation = "Input dispatching timed out";
+ } else {
+ annotation = "Input dispatching timed out (" + reason + ")";
+ }
+
+ if (proc != null) {
+ synchronized (mGlobalLock) {
+ if (proc.isDebugging()) {
+ return false;
+ }
+
+ if (proc.isInstrumenting()) {
+ Bundle info = new Bundle();
+ info.putString("shortMsg", "keyDispatchingTimedOut");
+ info.putString("longMsg", annotation);
+ mAm.finishInstrumentationLocked(
+ (ProcessRecord) proc.mOwner, Activity.RESULT_CANCELED, info);
+ return true;
+ }
+ }
+ mH.post(() -> {
+ mAm.mAppErrors.appNotResponding(
+ (ProcessRecord) proc.mOwner, activity, parent, aboveSystem, annotation);
+ });
+ }
+
+ return true;
+ }
+
/**
* Decide based on the configuration whether we should show the ANR,
* crash, etc dialogs. The idea is that if there is no affordance to
@@ -4784,6 +4868,30 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
return kept;
}
+ void scheduleAppGcsLocked() {
+ mH.post(() -> mAmInternal.scheduleAppGcs());
+ }
+
+ /**
+ * Returns the PackageManager. Used by classes hosted by {@link ActivityTaskManagerService}. The
+ * PackageManager could be unavailable at construction time and therefore needs to be accessed
+ * on demand.
+ */
+ IPackageManager getPackageManager() {
+ return AppGlobals.getPackageManager();
+ }
+
+ PackageManagerInternal getPackageManagerInternalLocked() {
+ if (mPmInternal == null) {
+ mPmInternal = LocalServices.getService(PackageManagerInternal.class);
+ }
+ return mPmInternal;
+ }
+
+ AppWarnings getAppWarningsLocked() {
+ return mAppWarnings;
+ }
+
void logAppTooSlow(WindowProcessController app, long startTime, String msg) {
if (true || Build.IS_USER) {
return;
@@ -5232,5 +5340,41 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
}
}
}
+
+ @Override
+ public long inputDispatchingTimedOut(int pid, boolean aboveSystem, String reason) {
+ synchronized (mGlobalLock) {
+ return ActivityTaskManagerService.this.inputDispatchingTimedOut(
+ pid, aboveSystem, reason);
+ }
+ }
+
+ @Override
+ public void onProcessMapped(int pid, WindowProcessController proc) {
+ synchronized (mGlobalLock) {
+ mPidMap.put(pid, proc);
+ }
+ }
+
+ @Override
+ public void onProcessUnMapped(int pid) {
+ synchronized (mGlobalLock) {
+ mPidMap.remove(pid);
+ }
+ }
+
+ @Override
+ public void onPackageDataCleared(String name) {
+ synchronized (mGlobalLock) {
+ mAppWarnings.onPackageDataCleared(name);
+ }
+ }
+
+ @Override
+ public void onPackageUninstalled(String name) {
+ synchronized (mGlobalLock) {
+ mAppWarnings.onPackageUninstalled(name);
+ }
+ }
}
}
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
index 7652dd4d26e1..2c580944926a 100644
--- a/services/core/java/com/android/server/am/AppErrors.java
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -436,7 +436,7 @@ class AppErrors {
* If this process was running instrumentation, finish now - it will be handled in
* {@link ActivityManagerService#handleAppDiedLocked}.
*/
- if (r != null && r.instr != null) {
+ if (r != null && r.getActiveInstrumentation() != null) {
return;
}
diff --git a/services/core/java/com/android/server/am/AppWarnings.java b/services/core/java/com/android/server/am/AppWarnings.java
index 30a384434675..a705180e48ee 100644
--- a/services/core/java/com/android/server/am/AppWarnings.java
+++ b/services/core/java/com/android/server/am/AppWarnings.java
@@ -17,7 +17,6 @@
package com.android.server.am;
import android.annotation.UiThread;
-import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.res.Configuration;
@@ -57,9 +56,9 @@ class AppWarnings {
private final HashMap<String, Integer> mPackageFlags = new HashMap<>();
- private final ActivityManagerService mAms;
+ private final ActivityTaskManagerService mAtm;
private final Context mUiContext;
- private final ConfigHandler mAmsHandler;
+ private final ConfigHandler mHandler;
private final UiHandler mUiHandler;
private final AtomicFile mConfigFile;
@@ -81,17 +80,17 @@ class AppWarnings {
* <p>
* <strong>Note:</strong> Must be called from the ActivityManagerService thread.
*
- * @param ams
+ * @param atm
* @param uiContext
- * @param amsHandler
+ * @param handler
* @param uiHandler
* @param systemDir
*/
- public AppWarnings(ActivityManagerService ams, Context uiContext, Handler amsHandler,
+ public AppWarnings(ActivityTaskManagerService atm, Context uiContext, Handler handler,
Handler uiHandler, File systemDir) {
- mAms = ams;
+ mAtm = atm;
mUiContext = uiContext;
- mAmsHandler = new ConfigHandler(amsHandler.getLooper());
+ mHandler = new ConfigHandler(handler.getLooper());
mUiHandler = new UiHandler(uiHandler.getLooper());
mConfigFile = new AtomicFile(new File(systemDir, CONFIG_FILE_NAME), "warnings-config");
@@ -104,7 +103,7 @@ class AppWarnings {
* @param r activity record for which the warning may be displayed
*/
public void showUnsupportedDisplaySizeDialogIfNeeded(ActivityRecord r) {
- final Configuration globalConfig = mAms.getGlobalConfiguration();
+ final Configuration globalConfig = mAtm.getGlobalConfiguration();
if (globalConfig.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
&& r.appInfo.requiresSmallestWidthDp > globalConfig.smallestScreenWidthDp) {
mUiHandler.showUnsupportedDisplaySizeDialog(r);
@@ -211,7 +210,7 @@ class AppWarnings {
synchronized (mPackageFlags) {
mPackageFlags.remove(name);
- mAmsHandler.scheduleWrite();
+ mHandler.scheduleWrite();
}
}
@@ -351,7 +350,7 @@ class AppWarnings {
} else {
mPackageFlags.remove(name);
}
- mAmsHandler.scheduleWrite();
+ mHandler.scheduleWrite();
}
}
}
@@ -430,10 +429,10 @@ class AppWarnings {
}
/**
- * Handles messages on the ActivityManagerService thread.
+ * Handles messages on the ActivityTaskManagerService thread.
*/
private final class ConfigHandler extends Handler {
- private static final int MSG_WRITE = ActivityManagerService.FIRST_COMPAT_MODE_MSG;
+ private static final int MSG_WRITE = 1;
private static final int DELAY_MSG_WRITE = 10000;
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index 046cfc7820b5..b36b5d35f28e 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -1462,7 +1462,7 @@ public final class BroadcastQueue {
// If the receiver app is being debugged we quietly ignore unresponsiveness, just
// tidying up and moving on to the next broadcast without crashing or ANRing this
// app just because it's stopped at a breakpoint.
- final boolean debugging = (r.curApp != null && r.curApp.debugging);
+ final boolean debugging = (r.curApp != null && r.curApp.isDebugging());
Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
+ ", started " + (now - r.receiverTime) + "ms ago");
diff --git a/services/core/java/com/android/server/am/CompatModeDialog.java b/services/core/java/com/android/server/am/CompatModeDialog.java
deleted file mode 100644
index 202cc7cad79d..000000000000
--- a/services/core/java/com/android/server/am/CompatModeDialog.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.am;
-
-import android.app.ActivityManager;
-import android.app.Dialog;
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.view.Gravity;
-import android.view.View;
-import android.view.Window;
-import android.view.WindowManager;
-import android.widget.CheckBox;
-import android.widget.CompoundButton;
-import android.widget.Switch;
-
-public final class CompatModeDialog extends Dialog {
- final ActivityManagerService mService;
- final ApplicationInfo mAppInfo;
-
- final Switch mCompatEnabled;
- final CheckBox mAlwaysShow;
- final View mHint;
-
- public CompatModeDialog(ActivityManagerService service, Context context,
- ApplicationInfo appInfo) {
- super(context, com.android.internal.R.style.Theme_Holo_Dialog_MinWidth);
- setCancelable(true);
- setCanceledOnTouchOutside(true);
- getWindow().requestFeature(Window.FEATURE_NO_TITLE);
- getWindow().setType(WindowManager.LayoutParams.TYPE_PHONE);
- getWindow().setGravity(Gravity.BOTTOM|Gravity.CENTER_HORIZONTAL);
- mService = service;
- mAppInfo = appInfo;
-
- setContentView(com.android.internal.R.layout.am_compat_mode_dialog);
- mCompatEnabled = (Switch)findViewById(com.android.internal.R.id.compat_checkbox);
- mCompatEnabled.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
- @Override
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- synchronized (mService) {
- mService.mCompatModePackages.setPackageScreenCompatModeLocked(
- mAppInfo.packageName,
- mCompatEnabled.isChecked() ? ActivityManager.COMPAT_MODE_ENABLED
- : ActivityManager.COMPAT_MODE_DISABLED);
- updateControls();
- }
- }
- });
- mAlwaysShow = (CheckBox)findViewById(com.android.internal.R.id.ask_checkbox);
- mAlwaysShow.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
- @Override
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- synchronized (mService) {
- mService.mCompatModePackages.setPackageAskCompatModeLocked(
- mAppInfo.packageName, mAlwaysShow.isChecked());
- updateControls();
- }
- }
- });
- mHint = findViewById(com.android.internal.R.id.reask_hint);
-
- updateControls();
- }
-
- void updateControls() {
- synchronized (mService) {
- int mode = mService.mCompatModePackages.computeCompatModeLocked(mAppInfo);
- mCompatEnabled.setChecked(mode == ActivityManager.COMPAT_MODE_ENABLED);
- boolean ask = mService.mCompatModePackages.getPackageAskCompatModeLocked(
- mAppInfo.packageName);
- mAlwaysShow.setChecked(ask);
- mHint.setVisibility(ask ? View.INVISIBLE : View.VISIBLE);
- }
- }
-}
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index b33ce2b71019..8c552b98698a 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -187,8 +187,9 @@ final class ProcessRecord implements WindowProcessListener {
int lruSeq; // Sequence id for identifying LRU update cycles
CompatibilityInfo compat; // last used compatibility mode
IBinder.DeathRecipient deathRecipient; // Who is watching for the death.
- ActiveInstrumentation instr;// Set to currently active instrumentation running in process
- boolean usingWrapper; // Set to true when process was launched with a wrapper attached
+ private ActiveInstrumentation mInstr; // Set to currently active instrumentation running in
+ // process.
+ private boolean mUsingWrapper; // Set to true when process was launched with a wrapper attached
final ArraySet<BroadcastRecord> curReceivers = new ArraySet<BroadcastRecord>();// receivers currently running in the app
long whenUnimportant; // When (uptime) the process last became unimportant
long lastCpuTime; // How long proc has run CPU at last check
@@ -232,7 +233,7 @@ final class ProcessRecord implements WindowProcessListener {
private boolean mNotResponding; // does the app have a not responding dialog?
Dialog anrDialog; // dialog being displayed due to app not resp.
boolean removed; // has app package been removed from device?
- boolean debugging; // was app launched for debugging?
+ private boolean mDebugging; // was app launched for debugging?
boolean waitedForDebugger; // has process show wait for debugger dialog?
Dialog waitDialog; // current wait for debugger dialog
@@ -317,8 +318,8 @@ final class ProcessRecord implements WindowProcessListener {
pw.println("}");
}
pw.print(prefix); pw.print("compat="); pw.println(compat);
- if (instr != null) {
- pw.print(prefix); pw.print("instr="); pw.println(instr);
+ if (mInstr != null) {
+ pw.print(prefix); pw.print("mInstr="); pw.println(mInstr);
}
pw.print(prefix); pw.print("thread="); pw.println(thread);
pw.print(prefix); pw.print("pid="); pw.print(pid); pw.print(" starting=");
@@ -435,9 +436,9 @@ final class ProcessRecord implements WindowProcessListener {
pw.print(" killedByAm="); pw.print(killedByAm);
pw.print(" waitingToKill="); pw.println(waitingToKill);
}
- if (debugging || mCrashing || crashDialog != null || mNotResponding
+ if (mDebugging || mCrashing || crashDialog != null || mNotResponding
|| anrDialog != null || bad) {
- pw.print(prefix); pw.print("debugging="); pw.print(debugging);
+ pw.print(prefix); pw.print("mDebugging="); pw.print(mDebugging);
pw.print(" mCrashing="); pw.print(mCrashing);
pw.print(" "); pw.print(crashDialog);
pw.print(" mNotResponding="); pw.print(mNotResponding);
@@ -975,6 +976,33 @@ final class ProcessRecord implements WindowProcessListener {
return mHasForegroundServices;
}
+ void setDebugging(boolean debugging) {
+ mDebugging = debugging;
+ mWindowProcessController.setDebugging(debugging);
+ }
+
+ boolean isDebugging() {
+ return mDebugging;
+ }
+
+ void setUsingWrapper(boolean usingWrapper) {
+ mUsingWrapper = usingWrapper;
+ mWindowProcessController.setUsingWrapper(usingWrapper);
+ }
+
+ boolean isUsingWrapper() {
+ return mUsingWrapper;
+ }
+
+ void setActiveInstrumentation(ActiveInstrumentation instr) {
+ mInstr = instr;
+ mWindowProcessController.setInstrumenting(instr != null);
+ }
+
+ ActiveInstrumentation getActiveInstrumentation() {
+ return mInstr;
+ }
+
@Override
public void clearProfilerIfNeeded() {
synchronized (mService) {
diff --git a/services/core/java/com/android/server/am/RecentTasks.java b/services/core/java/com/android/server/am/RecentTasks.java
index 230810b58515..fb6b5c1f05ec 100644
--- a/services/core/java/com/android/server/am/RecentTasks.java
+++ b/services/core/java/com/android/server/am/RecentTasks.java
@@ -288,7 +288,7 @@ class RecentTasks {
* @return whether the home app is also the active handler of recent tasks.
*/
boolean isRecentsComponentHomeActivity(int userId) {
- final ComponentName defaultHomeActivity = mService.mAm.getPackageManagerInternalLocked()
+ final ComponentName defaultHomeActivity = mService.getPackageManagerInternalLocked()
.getDefaultHomeActivity(userId);
return defaultHomeActivity != null && mRecentsComponent != null &&
defaultHomeActivity.getPackageName().equals(mRecentsComponent.getPackageName());
diff --git a/services/core/java/com/android/server/am/WindowProcessController.java b/services/core/java/com/android/server/am/WindowProcessController.java
index d4c9bcb1c826..e5551b51a093 100644
--- a/services/core/java/com/android/server/am/WindowProcessController.java
+++ b/services/core/java/com/android/server/am/WindowProcessController.java
@@ -93,6 +93,12 @@ public class WindowProcessController {
private volatile String mRequiredAbi;
// Running any services that are foreground?
private volatile boolean mHasForegroundServices;
+ // was app launched for debugging?
+ private volatile boolean mDebugging;
+ // Active instrumentation running in process?
+ private volatile boolean mInstrumenting;
+ // Set to true when process was launched with a wrapper attached
+ private volatile boolean mUsingWrapper;
// Thread currently set for VR scheduling
int mVrThreadTid;
@@ -189,6 +195,30 @@ public class WindowProcessController {
return mRequiredAbi;
}
+ public void setDebugging(boolean debugging) {
+ mDebugging = debugging;
+ }
+
+ boolean isDebugging() {
+ return mDebugging;
+ }
+
+ public void setUsingWrapper(boolean usingWrapper) {
+ mUsingWrapper = usingWrapper;
+ }
+
+ boolean isUsingWrapper() {
+ return mUsingWrapper;
+ }
+
+ public void setInstrumenting(boolean instrumenting) {
+ mInstrumenting = instrumenting;
+ }
+
+ boolean isInstrumenting() {
+ return mInstrumenting;
+ }
+
public void addPackage(String packageName) {
synchronized (mAtm.mGlobalLock) {
mPkgList.add(packageName);
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
index bfecd9d99cd9..83075ed24e33 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
@@ -274,4 +274,11 @@ public abstract class ActivityTaskManagerInternal {
public abstract void enableScreenAfterBoot(boolean booted);
public abstract boolean showStrictModeViolationDialog();
public abstract void showSystemReadyErrorDialogsIfNeeded();
+
+ public abstract long inputDispatchingTimedOut(int pid, boolean aboveSystem, String reason);
+ public abstract void onProcessMapped(int pid, WindowProcessController proc);
+ public abstract void onProcessUnMapped(int pid);
+
+ public abstract void onPackageDataCleared(String name);
+ public abstract void onPackageUninstalled(String name);
}
diff --git a/services/core/java/com/android/server/wm/InputManagerCallback.java b/services/core/java/com/android/server/wm/InputManagerCallback.java
index 016921df6047..b5e2f01d8fbb 100644
--- a/services/core/java/com/android/server/wm/InputManagerCallback.java
+++ b/services/core/java/com/android/server/wm/InputManagerCallback.java
@@ -123,17 +123,14 @@ final class InputManagerCallback implements InputManagerService.WindowManagerCal
return appWindowToken.mInputDispatchingTimeoutNanos;
}
} else if (windowState != null) {
- try {
- // Notify the activity manager about the timeout and let it decide whether
- // to abort dispatching or keep waiting.
- long timeout = ActivityManager.getService().inputDispatchingTimedOut(
- windowState.mSession.mPid, aboveSystem, reason);
- if (timeout >= 0) {
- // The activity manager declined to abort dispatching.
- // Wait a bit longer and timeout again later.
- return timeout * 1000000L; // nanoseconds
- }
- } catch (RemoteException ex) {
+ // Notify the activity manager about the timeout and let it decide whether
+ // to abort dispatching or keep waiting.
+ long timeout = mService.mAtmInternal.inputDispatchingTimedOut(
+ windowState.mSession.mPid, aboveSystem, reason);
+ if (timeout >= 0) {
+ // The activity manager declined to abort dispatching.
+ // Wait a bit longer and timeout again later.
+ return timeout * 1000000L; // nanoseconds
}
}
return 0; // abort dispatching
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStartInterceptorTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityStartInterceptorTest.java
index 420987d03509..41c7f1d787a4 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityStartInterceptorTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStartInterceptorTest.java
@@ -123,7 +123,7 @@ public class ActivityStartInterceptorTest {
mDevicePolicyManager);
when(mDevicePolicyManager.createShowAdminSupportIntent(TEST_USER_ID, true))
.thenReturn(ADMIN_SUPPORT_INTENT);
- when(mAm.getPackageManagerInternalLocked()).thenReturn(mPackageManagerInternal);
+ when(mService.getPackageManagerInternalLocked()).thenReturn(mPackageManagerInternal);
// Mock UserManager
when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
@@ -136,7 +136,7 @@ public class ActivityStartInterceptorTest {
thenReturn(CONFIRM_CREDENTIALS_INTENT);
// Mock PackageManager
- when(mAm.getPackageManager()).thenReturn(mPackageManager);
+ when(mService.getPackageManager()).thenReturn(mPackageManager);
when(mPackageManager.getHarmfulAppWarning(TEST_PACKAGE_NAME, TEST_USER_ID))
.thenReturn(null);
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
index 7e8697d95f51..a9e0aa805c37 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
@@ -32,12 +32,16 @@ import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
+import android.app.ActivityManagerInternal;
import android.app.ActivityOptions;
+import android.content.pm.PackageManagerInternal;
import com.android.server.uri.UriGrantsManagerInternal;
+import com.android.server.wm.ActivityTaskManagerInternal;
import com.android.server.wm.DisplayWindowController;
import org.junit.Rule;
@@ -128,17 +132,16 @@ public class ActivityTestsBase {
}
ActivityManagerService setupActivityManagerService(TestActivityTaskManagerService atm) {
- final ActivityManagerService am = spy(new TestActivityManagerService(mContext, atm));
+ final TestActivityManagerService am = spy(new TestActivityManagerService(mContext, atm));
setupActivityManagerService(am, atm);
return am;
}
- void setupActivityManagerService(ActivityManagerService am, ActivityTaskManagerService atm) {
+ void setupActivityManagerService(
+ TestActivityManagerService am, TestActivityTaskManagerService atm) {
atm.setActivityManagerService(am);
- atm.mAmInternal = am.new LocalService();
- am.mAtmInternal = atm.new LocalService();
- am.mUgmInternal = mock(UriGrantsManagerInternal.class);
- atm.mUgmInternal = mock(UriGrantsManagerInternal.class);
+ atm.mAmInternal = am.getLocalService();
+ am.mAtmInternal = atm.getLocalService();
// Makes sure the supervisor is using with the spy object.
atm.mStackSupervisor.setService(atm);
doReturn(mock(IPackageManager.class)).when(am).getPackageManager();
@@ -378,6 +381,8 @@ public class ActivityTestsBase {
protected static class TestActivityTaskManagerService extends ActivityTaskManagerService {
private LockTaskController mLockTaskController;
+ private ActivityTaskManagerInternal mInternal;
+ private PackageManagerInternal mPmInternal;
TestActivityTaskManagerService(Context context) {
super(context);
@@ -386,6 +391,7 @@ public class ActivityTestsBase {
mSupportsSplitScreenMultiWindow = true;
mSupportsFreeformWindowManagement = true;
mSupportsPictureInPicture = true;
+ mUgmInternal = mock(UriGrantsManagerInternal.class);
}
@Override
@@ -430,16 +436,34 @@ public class ActivityTestsBase {
protected ActivityStackSupervisor createTestSupervisor() {
return new TestActivityStackSupervisor(this, mH.getLooper());
}
+
+ ActivityTaskManagerInternal getLocalService() {
+ if (mInternal == null) {
+ mInternal = new ActivityTaskManagerService.LocalService();
+ }
+ return mInternal;
+ }
+
+ PackageManagerInternal getPackageManagerInternalLocked() {
+ if (mPmInternal == null) {
+ mPmInternal = mock(PackageManagerInternal.class);
+ doReturn(false).when(mPmInternal).isPermissionsReviewRequired(anyString(), anyInt());
+ }
+ return mPmInternal;
+ }
}
/**
* An {@link ActivityManagerService} subclass which provides a test
* {@link ActivityStackSupervisor}.
*/
- protected static class TestActivityManagerService extends ActivityManagerService {
+ static class TestActivityManagerService extends ActivityManagerService {
+
+ private ActivityManagerInternal mInternal;
TestActivityManagerService(Context context, TestActivityTaskManagerService atm) {
super(context, atm);
+ mUgmInternal = mock(UriGrantsManagerInternal.class);
}
@Override
@@ -450,6 +474,13 @@ public class ActivityTestsBase {
Configuration getGlobalConfiguration() {
return mContext.getResources().getConfiguration();
}
+
+ ActivityManagerInternal getLocalService() {
+ if (mInternal == null) {
+ mInternal = new LocalService();
+ }
+ return mInternal;
+ }
}
/**
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 37de79524ee3..227a70f7a5a3 100644
--- a/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java
@@ -115,7 +115,8 @@ public class RecentTasksTest extends ActivityTestsBase {
mTaskPersister = new TestTaskPersister(mContext.getFilesDir());
mService = spy(new MyTestActivityTaskManagerService(mContext));
- final ActivityManagerService am = spy(new MyTestActivityManagerService(mContext, mService));
+ final TestActivityManagerService am =
+ spy(new MyTestActivityManagerService(mContext, mService));
setupActivityManagerService(am, mService);
mRecentTasks = (TestRecentTasks) mService.getRecentTasks();
mRecentTasks.loadParametersFromResources(mContext.getResources());