diff options
| author | 2018-07-29 09:29:35 +0000 | |
|---|---|---|
| committer | 2018-07-29 09:29:35 +0000 | |
| commit | fab85f0fc33da068502c4debc2933f61fcd905fc (patch) | |
| tree | 6b0cd75649eaaa9478e1a9b89f97777beee60de5 | |
| parent | a1b12c82a1b466967ef285f53ddc6850243e4d84 (diff) | |
| parent | 008163e777d5ed3779195129b72b6947f7086847 (diff) | |
Merge changes Ide697f9f,Ia76c5741
* changes:
Moved AppWarnings handling to ActivityTaskManagerService (15/n)
Moved input time out handling to ActivityTaskManagerService (14/n)
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()); |