diff options
Diffstat (limited to 'com/android/server/am/ActivityManagerService.java')
-rw-r--r-- | com/android/server/am/ActivityManagerService.java | 1262 |
1 files changed, 1025 insertions, 237 deletions
diff --git a/com/android/server/am/ActivityManagerService.java b/com/android/server/am/ActivityManagerService.java index d92b3b86..2ccda7db 100644 --- a/com/android/server/am/ActivityManagerService.java +++ b/com/android/server/am/ActivityManagerService.java @@ -19,16 +19,18 @@ 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.CHANGE_DEVICE_IDLE_TEMP_WHITELIST; +import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS; import static android.Manifest.permission.INTERACT_ACROSS_USERS; import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW; import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS; import static android.Manifest.permission.READ_FRAME_BUFFER; import static android.Manifest.permission.REMOVE_TASKS; +import static android.Manifest.permission.START_ACTIVITY_AS_CALLER; import static android.Manifest.permission.START_TASKS_FROM_RECENTS; -import static android.app.ActivityManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT; import static android.app.ActivityManager.LOCK_TASK_MODE_NONE; import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW; +import static android.app.ActivityManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT; import static android.app.ActivityManager.StackId.INVALID_STACK_ID; import static android.app.ActivityManagerInternal.ASSIST_KEY_CONTENT; import static android.app.ActivityManagerInternal.ASSIST_KEY_DATA; @@ -37,6 +39,7 @@ import static android.app.ActivityManagerInternal.ASSIST_KEY_STRUCTURE; import static android.app.ActivityThread.PROC_START_SEQ_IDENT; import static android.app.AppOpsManager.OP_ASSIST_STRUCTURE; import static android.app.AppOpsManager.OP_NONE; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; @@ -119,6 +122,7 @@ import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICAT import static android.text.format.DateUtils.DAY_IN_MILLIS; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.INVALID_DISPLAY; + import static com.android.internal.util.XmlUtils.readBooleanAttribute; import static com.android.internal.util.XmlUtils.readIntAttribute; import static com.android.internal.util.XmlUtils.readLongAttribute; @@ -192,11 +196,12 @@ import static com.android.server.am.TaskRecord.INVALID_TASK_ID; import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK; import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT; import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE; -import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN; -import static com.android.server.wm.AppTransition.TRANSIT_NONE; -import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE; -import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN; -import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT; +import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN; +import static android.view.WindowManager.TRANSIT_NONE; +import static android.view.WindowManager.TRANSIT_TASK_IN_PLACE; +import static android.view.WindowManager.TRANSIT_TASK_OPEN; +import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT; + import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; import static org.xmlpull.v1.XmlPullParser.START_TAG; @@ -213,6 +218,7 @@ import android.app.ActivityManager.TaskSnapshot; import android.app.ActivityManagerInternal; import android.app.ActivityManagerInternal.ScreenObserver; import android.app.ActivityManagerInternal.SleepToken; +import android.app.ActivityManagerProto; import android.app.ActivityOptions; import android.app.ActivityThread; import android.app.AlertDialog; @@ -276,8 +282,8 @@ import android.content.pm.IPackageManager; import android.content.pm.InstrumentationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; -import android.content.pm.PackageManagerInternal; import android.content.pm.PackageManager.NameNotFoundException; +import android.content.pm.PackageManagerInternal; import android.content.pm.ParceledListSlice; import android.content.pm.PathPermission; import android.content.pm.PermissionInfo; @@ -293,6 +299,7 @@ import android.database.ContentObserver; import android.graphics.Bitmap; import android.graphics.Point; import android.graphics.Rect; +import android.hardware.display.DisplayManagerInternal; import android.location.LocationManager; import android.media.audiofx.AudioEffect; import android.metrics.LogMaker; @@ -354,22 +361,25 @@ import android.text.style.SuggestionSpan; import android.util.ArrayMap; import android.util.ArraySet; import android.util.AtomicFile; -import android.util.LongSparseArray; -import android.util.StatsLog; -import android.util.TimingsTraceLog; import android.util.DebugUtils; import android.util.EventLog; import android.util.Log; +import android.util.LongSparseArray; import android.util.Pair; import android.util.PrintWriterPrinter; import android.util.Slog; import android.util.SparseArray; import android.util.SparseIntArray; +import android.util.StatsLog; import android.util.TimeUtils; +import android.util.TimingsTraceLog; import android.util.Xml; import android.util.proto.ProtoOutputStream; +import android.util.proto.ProtoUtils; import android.view.Gravity; +import android.view.IRecentsAnimationRunner; import android.view.LayoutInflater; +import android.view.RemoteAnimationDefinition; import android.view.View; import android.view.WindowManager; @@ -391,12 +401,14 @@ import com.android.internal.notification.SystemNotificationChannels; import com.android.internal.os.BackgroundThread; import com.android.internal.os.BatteryStatsImpl; import com.android.internal.os.BinderInternal; +import com.android.internal.os.logging.MetricsLoggerWrapper; import com.android.internal.os.ByteTransferPipe; import com.android.internal.os.IResultReceiver; import com.android.internal.os.ProcessCpuTracker; import com.android.internal.os.TransferPipe; import com.android.internal.os.Zygote; import com.android.internal.policy.IKeyguardDismissCallback; +import com.android.internal.policy.KeyguardDismissCallback; import com.android.internal.telephony.TelephonyIntents; import com.android.internal.util.ArrayUtils; import com.android.internal.util.DumpUtils; @@ -421,12 +433,16 @@ import com.android.server.SystemServiceManager; import com.android.server.ThreadPriorityBooster; import com.android.server.Watchdog; import com.android.server.am.ActivityStack.ActivityState; -import com.android.server.am.EventLogTags; import com.android.server.am.proto.ActivityManagerServiceProto; import com.android.server.am.proto.BroadcastProto; import com.android.server.am.proto.GrantUriProto; +import com.android.server.am.proto.ImportanceTokenProto; import com.android.server.am.proto.MemInfoProto; import com.android.server.am.proto.NeededUriGrantsProto; +import com.android.server.am.proto.ProcessOomProto; +import com.android.server.am.proto.ProcessToGcProto; +import com.android.server.am.proto.ProcessesProto; +import com.android.server.am.proto.ProcessesProto.UidObserverRegistrationProto; import com.android.server.am.proto.StickyBroadcastProto; import com.android.server.firewall.IntentFirewall; import com.android.server.job.JobSchedulerInternal; @@ -435,7 +451,14 @@ import com.android.server.pm.Installer.InstallerException; import com.android.server.utils.PriorityDump; import com.android.server.vr.VrManagerInternal; import com.android.server.wm.PinnedStackWindowController; +import com.android.server.wm.RecentsAnimationController; import com.android.server.wm.WindowManagerService; + +import dalvik.system.VMRuntime; + +import libcore.io.IoUtils; +import libcore.util.EmptyArray; + import com.google.android.collect.Lists; import com.google.android.collect.Maps; @@ -471,14 +494,10 @@ import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; -import dalvik.system.VMRuntime; - -import libcore.io.IoUtils; -import libcore.util.EmptyArray; - public class ActivityManagerService extends IActivityManager.Stub implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { @@ -549,6 +568,23 @@ public class ActivityManagerService extends IActivityManager.Stub // could take much longer than usual. static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; + // Permission tokens are used to temporarily granted a trusted app the ability to call + // #startActivityAsCaller. A client is expected to dump its token after this time has elapsed, + // showing any appropriate error messages to the user. + private static final long START_AS_CALLER_TOKEN_TIMEOUT = + 10 * DateUtils.MINUTE_IN_MILLIS; + + // How long before the service actually expires a token. This is slightly longer than + // START_AS_CALLER_TOKEN_TIMEOUT, to provide a buffer so clients will rarely encounter the + // expiration exception. + private static final long START_AS_CALLER_TOKEN_TIMEOUT_IMPL = + START_AS_CALLER_TOKEN_TIMEOUT + 2*1000; + + // How long the service will remember expired tokens, for the purpose of providing error + // messaging when a client uses an expired token. + private static final long START_AS_CALLER_TOKEN_EXPIRED_TIMEOUT = + START_AS_CALLER_TOKEN_TIMEOUT_IMPL + 20 * DateUtils.MINUTE_IN_MILLIS; + // How long we allow a receiver to run before giving up on it. static final int BROADCAST_FG_TIMEOUT = 10*1000; static final int BROADCAST_BG_TIMEOUT = 60*1000; @@ -657,6 +693,13 @@ public class ActivityManagerService extends IActivityManager.Stub final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>(); + // Activity tokens of system activities that are delegating their call to + // #startActivityByCaller, keyed by the permissionToken granted to the delegate. + final HashMap<IBinder, IBinder> mStartActivitySources = new HashMap<>(); + + // Permission tokens that have expired, but we remember for error reporting. + final ArrayList<IBinder> mExpiredStartAsCallerTokens = new ArrayList<>(); + public final IntentFirewall mIntentFirewall; // Whether we should show our dialogs (ANR, crash, etc) or just perform their @@ -930,6 +973,16 @@ public class ActivityManagerService extends IActivityManager.Stub return "ImportanceToken { " + Integer.toHexString(System.identityHashCode(this)) + " " + reason + " " + pid + " " + token + " }"; } + + void writeToProto(ProtoOutputStream proto, long fieldId) { + final long pToken = proto.start(fieldId); + proto.write(ImportanceTokenProto.PID, pid); + if (token != null) { + proto.write(ImportanceTokenProto.TOKEN, token.toString()); + } + proto.write(ImportanceTokenProto.REASON, reason); + proto.end(pToken); + } } final SparseArray<ImportanceToken> mImportantProcesses = new SparseArray<ImportanceToken>(); @@ -1308,6 +1361,14 @@ public class ActivityManagerService extends IActivityManager.Stub duration = _duration; tag = _tag; } + + void writeToProto(ProtoOutputStream proto, long fieldId) { + final long token = proto.start(fieldId); + proto.write(ProcessesProto.PendingTempWhitelist.TARGET_UID, targetUid); + proto.write(ProcessesProto.PendingTempWhitelist.DURATION_MS, duration); + proto.write(ProcessesProto.PendingTempWhitelist.TAG, tag); + proto.end(token); + } } final SparseArray<PendingTempWhitelist> mPendingTempWhitelist = new SparseArray<>(); @@ -1632,6 +1693,20 @@ public class ActivityManagerService extends IActivityManager.Stub final SparseIntArray lastProcStates; + // Please keep the enum lists in sync + private static int[] ORIG_ENUMS = new int[]{ + ActivityManager.UID_OBSERVER_IDLE, + ActivityManager.UID_OBSERVER_ACTIVE, + ActivityManager.UID_OBSERVER_GONE, + ActivityManager.UID_OBSERVER_PROCSTATE, + }; + private static int[] PROTO_ENUMS = new int[]{ + ActivityManagerProto.UID_OBSERVER_FLAG_IDLE, + ActivityManagerProto.UID_OBSERVER_FLAG_ACTIVE, + ActivityManagerProto.UID_OBSERVER_FLAG_GONE, + ActivityManagerProto.UID_OBSERVER_FLAG_PROCSTATE, + }; + UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) { uid = _uid; pkg = _pkg; @@ -1643,6 +1718,25 @@ public class ActivityManagerService extends IActivityManager.Stub lastProcStates = null; } } + + void writeToProto(ProtoOutputStream proto, long fieldId) { + final long token = proto.start(fieldId); + proto.write(UidObserverRegistrationProto.UID, uid); + proto.write(UidObserverRegistrationProto.PACKAGE, pkg); + ProtoUtils.writeBitWiseFlagsToProtoEnum(proto, UidObserverRegistrationProto.FLAGS, + which, ORIG_ENUMS, PROTO_ENUMS); + proto.write(UidObserverRegistrationProto.CUT_POINT, cutpoint); + if (lastProcStates != null) { + final int NI = lastProcStates.size(); + for (int i=0; i<NI; i++) { + final long pToken = proto.start(UidObserverRegistrationProto.LAST_PROC_STATES); + proto.write(UidObserverRegistrationProto.ProcState.UID, lastProcStates.keyAt(i)); + proto.write(UidObserverRegistrationProto.ProcState.STATE, lastProcStates.valueAt(i)); + proto.end(pToken); + } + } + proto.end(token); + } } final List<ScreenObserver> mScreenObservers = new ArrayList<>(); @@ -1776,6 +1870,8 @@ public class ActivityManagerService extends IActivityManager.Stub static final int PUSH_TEMP_WHITELIST_UI_MSG = 68; static final int SERVICE_FOREGROUND_CRASH_MSG = 69; static final int DISPATCH_OOM_ADJ_OBSERVER_MSG = 70; + static final int EXPIRE_START_AS_CALLER_TOKEN_MSG = 75; + static final int FORGET_START_AS_CALLER_TOKEN_MSG = 76; static final int FIRST_ACTIVITY_STACK_MSG = 100; static final int FIRST_BROADCAST_QUEUE_MSG = 200; @@ -2440,6 +2536,19 @@ public class ActivityManagerService extends IActivityManager.Stub } } } break; + case EXPIRE_START_AS_CALLER_TOKEN_MSG: { + synchronized (ActivityManagerService.this) { + final IBinder permissionToken = (IBinder)msg.obj; + mStartActivitySources.remove(permissionToken); + mExpiredStartAsCallerTokens.add(permissionToken); + } + } break; + case FORGET_START_AS_CALLER_TOKEN_MSG: { + synchronized (ActivityManagerService.this) { + final IBinder permissionToken = (IBinder)msg.obj; + mExpiredStartAsCallerTokens.remove(permissionToken); + } + } break; } } }; @@ -2521,13 +2630,15 @@ public class ActivityManagerService extends IActivityManager.Stub } } if (proc != null) { + long startTime = SystemClock.currentThreadTimeMillis(); long pss = Debug.getPss(pid, tmp, null); + long endTime = SystemClock.currentThreadTimeMillis(); synchronized (ActivityManagerService.this) { if (pss != 0 && proc.thread != null && proc.setProcState == procState && proc.pid == pid && proc.lastPssTime == lastPssTime) { num++; recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1], - SystemClock.uptimeMillis()); + endTime-startTime, SystemClock.uptimeMillis()); } } } @@ -2695,6 +2806,13 @@ public class ActivityManagerService extends IActivityManager.Stub } @Override + public void onBootPhase(int phase) { + if (phase == PHASE_SYSTEM_SERVICES_READY) { + mService.mBatteryStatsService.systemServicesReady(); + } + } + + @Override public void onCleanupUser(int userId) { mService.mBatteryStatsService.onCleanupUser(userId); } @@ -3949,6 +4067,12 @@ public class ActivityManagerService extends IActivityManager.Stub runtimeFlags |= Zygote.ONLY_USE_SYSTEM_OAT_FILES; } + if (app.info.isAllowedToUseHiddenApi()) { + // This app is allowed to use undocumented and private APIs. Set + // up its runtime with the appropriate flag. + runtimeFlags |= Zygote.DISABLE_HIDDEN_API_CHECKS; + } + String invokeWith = null; if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { // Debuggable apps may include a wrapper script with their library directory. @@ -4693,21 +4817,60 @@ public class ActivityManagerService extends IActivityManager.Stub .setRequestCode(requestCode) .setStartFlags(startFlags) .setProfilerInfo(profilerInfo) - .setMayWait(bOptions, userId) + .setActivityOptions(bOptions) + .setMayWait(userId) .execute(); } + /** + * Only callable from the system. This token grants a temporary permission to call + * #startActivityAsCallerWithToken. The token will time out after + * START_AS_CALLER_TOKEN_TIMEOUT if it is not used. + * + * @param delegatorToken The Binder token referencing the system Activity that wants to delegate + * the #startActivityAsCaller to another app. The "caller" will be the caller of this + * activity's token, not the delegate's caller (which is probably the delegator itself). + * + * @return Returns a token that can be given to a "delegate" app that may call + * #startActivityAsCaller + */ @Override - public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, - Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, - int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity, - int userId) { + public IBinder requestStartActivityPermissionToken(IBinder delegatorToken) { + int callingUid = Binder.getCallingUid(); + if (UserHandle.getAppId(callingUid) != SYSTEM_UID) { + throw new SecurityException("Only the system process can request a permission token, " + + "received request from uid: " + callingUid); + } + IBinder permissionToken = new Binder(); + synchronized (this) { + mStartActivitySources.put(permissionToken, delegatorToken); + } + + Message expireMsg = mHandler.obtainMessage(EXPIRE_START_AS_CALLER_TOKEN_MSG, + permissionToken); + mHandler.sendMessageDelayed(expireMsg, START_AS_CALLER_TOKEN_TIMEOUT_IMPL); + + Message forgetMsg = mHandler.obtainMessage(FORGET_START_AS_CALLER_TOKEN_MSG, + permissionToken); + mHandler.sendMessageDelayed(forgetMsg, START_AS_CALLER_TOKEN_EXPIRED_TIMEOUT); + return permissionToken; + } + + @Override + public final int startActivityAsCaller(IApplicationThread caller, + String callingPackage, Intent intent, String resolvedType, IBinder resultTo, + String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, + Bundle bOptions, IBinder permissionToken, boolean ignoreTargetSecurity, int userId) { // This is very dangerous -- it allows you to perform a start activity (including - // permission grants) as any app that may launch one of your own activities. So - // we will only allow this to be done from activities that are part of the core framework, - // and then only when they are running as the system. + // permission grants) as any app that may launch one of your own activities. So we only + // allow this in two cases: + // 1) The caller is an activity that is part of the core framework, and then only when it + // is running as the system. + // 2) The caller provides a valid permissionToken. Permission tokens are one-time use and + // can only be requested by a system activity, which may then delegate this call to + // another app. final ActivityRecord sourceRecord; final int targetUid; final String targetPackage; @@ -4715,17 +4878,47 @@ public class ActivityManagerService extends IActivityManager.Stub if (resultTo == null) { throw new SecurityException("Must be called from an activity"); } - sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); - if (sourceRecord == null) { - throw new SecurityException("Called with bad activity token: " + resultTo); + + final IBinder sourceToken; + if (permissionToken != null) { + // To even attempt to use a permissionToken, an app must also have this signature + // permission. + enforceCallingPermission(android.Manifest.permission.START_ACTIVITY_AS_CALLER, + "startActivityAsCaller"); + // If called with a permissionToken, we want the sourceRecord from the delegator + // activity that requested this token. + sourceToken = + mStartActivitySources.remove(permissionToken); + if (sourceToken == null) { + // Invalid permissionToken, check if it recently expired. + if (mExpiredStartAsCallerTokens.contains(permissionToken)) { + throw new SecurityException("Called with expired permission token: " + + permissionToken); + } else { + throw new SecurityException("Called with invalid permission token: " + + permissionToken); + } + } + } else { + // This method was called directly by the source. + sourceToken = resultTo; } - if (!sourceRecord.info.packageName.equals("android")) { - throw new SecurityException( - "Must be called from an activity that is declared in the android package"); + + sourceRecord = mStackSupervisor.isInAnyStackLocked(sourceToken); + if (sourceRecord == null) { + throw new SecurityException("Called with bad activity token: " + sourceToken); } if (sourceRecord.app == null) { throw new SecurityException("Called without a process attached to activity"); } + + // Whether called directly or from a delegate, the source activity must be from the + // android package. + if (!sourceRecord.info.packageName.equals("android")) { + throw new SecurityException("Must be called from an activity that is " + + "declared in the android package"); + } + if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) { // This is still okay, as long as this activity is running under the // uid of the original calling activity. @@ -4736,6 +4929,7 @@ public class ActivityManagerService extends IActivityManager.Stub + sourceRecord.launchedFromUid); } } + if (ignoreTargetSecurity) { if (intent.getComponent() == null) { throw new SecurityException( @@ -4764,7 +4958,8 @@ public class ActivityManagerService extends IActivityManager.Stub .setResultWho(resultWho) .setRequestCode(requestCode) .setStartFlags(startFlags) - .setMayWait(bOptions, userId) + .setActivityOptions(bOptions) + .setMayWait(userId) .setIgnoreTargetSecurity(ignoreTargetSecurity) .execute(); } catch (SecurityException e) { @@ -4800,7 +4995,8 @@ public class ActivityManagerService extends IActivityManager.Stub .setResultWho(resultWho) .setRequestCode(requestCode) .setStartFlags(startFlags) - .setMayWait(bOptions, userId) + .setActivityOptions(bOptions) + .setMayWait(userId) .setProfilerInfo(profilerInfo) .setWaitResult(res) .execute(); @@ -4824,7 +5020,8 @@ public class ActivityManagerService extends IActivityManager.Stub .setRequestCode(requestCode) .setStartFlags(startFlags) .setGlobalConfiguration(config) - .setMayWait(bOptions, userId) + .setActivityOptions(bOptions) + .setMayWait(userId) .execute(); } @@ -4879,7 +5076,8 @@ public class ActivityManagerService extends IActivityManager.Stub .setVoiceInteractor(interactor) .setStartFlags(startFlags) .setProfilerInfo(profilerInfo) - .setMayWait(bOptions, userId) + .setActivityOptions(bOptions) + .setMayWait(userId) .execute(); } @@ -4894,27 +5092,22 @@ public class ActivityManagerService extends IActivityManager.Stub .setCallingUid(callingUid) .setCallingPackage(callingPackage) .setResolvedType(resolvedType) - .setMayWait(bOptions, userId) + .setActivityOptions(bOptions) + .setMayWait(userId) .execute(); } @Override - public int startRecentsActivity(IAssistDataReceiver assistDataReceiver, Bundle options, - Bundle activityOptions, int userId) { - if (!mRecentTasks.isCallerRecents(Binder.getCallingUid())) { - String msg = "Permission Denial: startRecentsActivity() from pid=" - + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() - + " not recent tasks package"; - Slog.w(TAG, msg); - throw new SecurityException(msg); - } - - final int recentsUid = mRecentTasks.getRecentsComponentUid(); - final ComponentName recentsComponent = mRecentTasks.getRecentsComponent(); - final String recentsPackage = recentsComponent.getPackageName(); + public void startRecentsActivity(Intent intent, IAssistDataReceiver assistDataReceiver, + IRecentsAnimationRunner recentsAnimationRunner) { + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "startRecentsActivity()"); final long origId = Binder.clearCallingIdentity(); try { synchronized (this) { + final int recentsUid = mRecentTasks.getRecentsComponentUid(); + final ComponentName recentsComponent = mRecentTasks.getRecentsComponent(); + final String recentsPackage = recentsComponent.getPackageName(); + // If provided, kick off the request for the assist data in the background before // starting the activity if (assistDataReceiver != null) { @@ -4931,16 +5124,24 @@ public class ActivityManagerService extends IActivityManager.Stub recentsUid, recentsPackage); } - final Intent intent = new Intent(); - intent.setFlags(FLAG_ACTIVITY_NEW_TASK); - intent.setComponent(recentsComponent); - intent.putExtras(options); + // Start a new recents animation + final RecentsAnimation anim = new RecentsAnimation(this, mStackSupervisor, + mActivityStartController, mWindowManager, mUserController); + anim.startRecentsActivity(intent, recentsAnimationRunner, recentsComponent, + recentsUid); + } + } finally { + Binder.restoreCallingIdentity(origId); + } + } - return mActivityStartController.obtainStarter(intent, "startRecentsActivity") - .setCallingUid(recentsUid) - .setCallingPackage(recentsPackage) - .setMayWait(activityOptions, userId) - .execute(); + @Override + public void cancelRecentsAnimation() { + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()"); + final long origId = Binder.clearCallingIdentity(); + try { + synchronized (this) { + mWindowManager.cancelRecentsAnimation(); } } finally { Binder.restoreCallingIdentity(origId); @@ -5027,17 +5228,17 @@ public class ActivityManagerService extends IActivityManager.Stub if (intent != null && intent.hasFileDescriptors() == true) { throw new IllegalArgumentException("File descriptors passed in Intent"); } - ActivityOptions options = ActivityOptions.fromBundle(bOptions); + SafeActivityOptions options = SafeActivityOptions.fromBundle(bOptions); synchronized (this) { final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); if (r == null) { - ActivityOptions.abort(options); + SafeActivityOptions.abort(options); return false; } if (r.app == null || r.app.thread == null) { // The caller is not running... d'oh! - ActivityOptions.abort(options); + SafeActivityOptions.abort(options); return false; } intent = new Intent(intent); @@ -5082,7 +5283,7 @@ public class ActivityManagerService extends IActivityManager.Stub if (aInfo == null) { // Nobody who is next! - ActivityOptions.abort(options); + SafeActivityOptions.abort(options); if (debug) Slog.d(TAG, "Next matching activity: nothing found"); return false; } @@ -5144,10 +5345,13 @@ public class ActivityManagerService extends IActivityManager.Stub enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS, "startActivityFromRecents()"); + final int callingPid = Binder.getCallingPid(); + final int callingUid = Binder.getCallingUid(); final long origId = Binder.clearCallingIdentity(); try { synchronized (this) { - return mStackSupervisor.startActivityFromRecents(taskId, bOptions); + return mStackSupervisor.startActivityFromRecents(callingPid, callingUid, taskId, + SafeActivityOptions.fromBundle(bOptions)); } } finally { Binder.restoreCallingIdentity(origId); @@ -5164,7 +5368,8 @@ public class ActivityManagerService extends IActivityManager.Stub userId, false, ALLOW_FULL_ONLY, reason, null); // TODO: Switch to user app stacks here. int ret = mActivityStartController.startActivities(caller, -1, callingPackage, - intents, resolvedTypes, resultTo, bOptions, userId, reason); + intents, resolvedTypes, resultTo, SafeActivityOptions.fromBundle(bOptions), userId, + reason); return ret; } @@ -6233,7 +6438,7 @@ public class ActivityManagerService extends IActivityManager.Stub // Clear its pending alarms AlarmManagerInternal ami = LocalServices.getService(AlarmManagerInternal.class); - ami.removeAlarmsForUid(uid); + ami.removeAlarmsForUid(appInfo.uid); } } catch (RemoteException e) { } @@ -6539,13 +6744,17 @@ public class ActivityManagerService extends IActivityManager.Stub } } infos[i] = new Debug.MemoryInfo(); + long startTime = SystemClock.currentThreadTimeMillis(); Debug.getMemoryInfo(pids[i], infos[i]); + long endTime = SystemClock.currentThreadTimeMillis(); if (proc != null) { synchronized (this) { if (proc.thread != null && proc.setAdj == oomAdj) { // Record this for posterity if the process has been stable. proc.baseProcessTracker.addPss(infos[i].getTotalPss(), - infos[i].getTotalUss(), false, proc.pkgList); + infos[i].getTotalUss(), false, + ProcessStats.ADD_PSS_EXTERNAL_SLOW, endTime-startTime, + proc.pkgList); } } } @@ -6567,12 +6776,15 @@ public class ActivityManagerService extends IActivityManager.Stub } } long[] tmpUss = new long[1]; + long startTime = SystemClock.currentThreadTimeMillis(); pss[i] = Debug.getPss(pids[i], tmpUss, null); + long endTime = SystemClock.currentThreadTimeMillis(); if (proc != null) { synchronized (this) { if (proc.thread != null && proc.setAdj == oomAdj) { // Record this for posterity if the process has been stable. - proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); + proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, + ProcessStats.ADD_PSS_EXTERNAL, endTime-startTime, proc.pkgList); } } } @@ -7244,15 +7456,22 @@ public class ActivityManagerService extends IActivityManager.Stub } ProfilerInfo profilerInfo = null; - String agent = null; + String preBindAgent = null; if (mProfileApp != null && mProfileApp.equals(processName)) { mProfileProc = app; - profilerInfo = (mProfilerInfo != null && mProfilerInfo.profileFile != null) ? - new ProfilerInfo(mProfilerInfo) : null; - agent = mProfilerInfo != null ? mProfilerInfo.agent : null; + if (mProfilerInfo != null) { + // Send a profiler info object to the app if either a file is given, or + // an agent should be loaded at bind-time. + boolean needsInfo = mProfilerInfo.profileFile != null + || mProfilerInfo.attachAgentDuringBind; + profilerInfo = needsInfo ? new ProfilerInfo(mProfilerInfo) : null; + if (!mProfilerInfo.attachAgentDuringBind) { + preBindAgent = mProfilerInfo.agent; + } + } } else if (app.instr != null && app.instr.mProfileFile != null) { profilerInfo = new ProfilerInfo(app.instr.mProfileFile, null, 0, false, false, - null); + null, false); } boolean enableTrackAllocation = false; @@ -7321,8 +7540,8 @@ public class ActivityManagerService extends IActivityManager.Stub // If we were asked to attach an agent on startup, do so now, before we're binding // application code. - if (agent != null) { - thread.attachAgent(agent); + if (preBindAgent != null) { + thread.attachAgent(preBindAgent); } checkTime(startTime, "attachApplicationLocked: immediately before bindApplication"); @@ -7909,9 +8128,9 @@ public class ActivityManagerService extends IActivityManager.Stub flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT |PendingIntent.FLAG_UPDATE_CURRENT); - PendingIntentRecord.Key key = new PendingIntentRecord.Key( - type, packageName, activity, resultWho, - requestCode, intents, resolvedTypes, flags, bOptions, userId); + PendingIntentRecord.Key key = new PendingIntentRecord.Key(type, packageName, activity, + resultWho, requestCode, intents, resolvedTypes, flags, + SafeActivityOptions.fromBundle(bOptions), userId); WeakReference<PendingIntentRecord> ref; ref = mIntentSenderRecords.get(key); PendingIntentRecord rec = ref != null ? ref.get() : null; @@ -8360,8 +8579,7 @@ public class ActivityManagerService extends IActivityManager.Stub stack.setPictureInPictureAspectRatio(aspectRatio); stack.setPictureInPictureActions(actions); - MetricsLogger.action(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_ENTERED, - r.supportsEnterPipOnTaskSwitch); + MetricsLoggerWrapper.logPictureInPictureEnter(mContext, r.supportsEnterPipOnTaskSwitch); logPictureInPictureArgs(params); }; @@ -8370,22 +8588,12 @@ public class ActivityManagerService extends IActivityManager.Stub // entering picture-in-picture (this will prompt the user to authenticate if the // device is currently locked). try { - dismissKeyguard(token, new IKeyguardDismissCallback.Stub() { - @Override - public void onDismissError() throws RemoteException { - // Do nothing - } - + dismissKeyguard(token, new KeyguardDismissCallback() { @Override public void onDismissSucceeded() throws RemoteException { mHandler.post(enterPipRunnable); } - - @Override - public void onDismissCancelled() throws RemoteException { - // Do nothing - } - }); + }, null /* message */); } catch (RemoteException e) { // Local call } @@ -8583,6 +8791,16 @@ public class ActivityManagerService extends IActivityManager.Stub } return false; } + + @Override + public int getPackageUid(String packageName, int flags) { + try { + return mActivityManagerService.mContext.getPackageManager() + .getPackageUid(packageName, flags); + } catch (NameNotFoundException nnfe) { + return -1; + } + } } class IntentFirewallInterface implements IntentFirewall.AMSInterface { @@ -8806,7 +9024,7 @@ public class ActivityManagerService extends IActivityManager.Stub case AppOpsManager.MODE_ALLOWED: // If force-background-check is enabled, restrict all apps that aren't whitelisted. if (mForceBackgroundCheck && - UserHandle.isApp(uid) && + !UserHandle.isCore(uid) && !isOnDeviceIdleWhitelistLocked(uid)) { if (DEBUG_BACKGROUND_CHECK) { Slog.i(TAG, "Force background check: " + @@ -10386,10 +10604,9 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public Bitmap getTaskDescriptionIcon(String filePath, int userId) { - if (userId != UserHandle.getCallingUserId()) { - enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, - "getTaskDescriptionIcon"); - } + userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), + userId, false, ALLOW_FULL_ONLY, "getTaskDescriptionIcon", null); + final File passedIconFile = new File(filePath); final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId), passedIconFile.getName()); @@ -10404,9 +10621,13 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public void startInPlaceAnimationOnFrontMostApplication(Bundle opts) throws RemoteException { - final ActivityOptions activityOptions = ActivityOptions.fromBundle(opts); - if (activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE || - activityOptions.getCustomInPlaceResId() == 0) { + final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(opts); + final ActivityOptions activityOptions = safeOptions != null + ? safeOptions.getOptions(mStackSupervisor) + : null; + if (activityOptions == null + || activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE + || activityOptions.getCustomInPlaceResId() == 0) { throw new IllegalArgumentException("Expected in-place ActivityOption " + "with valid animation"); } @@ -10509,16 +10730,17 @@ public class ActivityManagerService extends IActivityManager.Stub if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId); synchronized(this) { - moveTaskToFrontLocked(taskId, flags, bOptions, false /* fromRecents */); + moveTaskToFrontLocked(taskId, flags, SafeActivityOptions.fromBundle(bOptions), + false /* fromRecents */); } } - void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions, boolean fromRecents) { - ActivityOptions options = ActivityOptions.fromBundle(bOptions); + void moveTaskToFrontLocked(int taskId, int flags, SafeActivityOptions options, + boolean fromRecents) { if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), Binder.getCallingUid(), -1, -1, "Task to front")) { - ActivityOptions.abort(options); + SafeActivityOptions.abort(options); return; } final long origId = Binder.clearCallingIdentity(); @@ -10532,7 +10754,10 @@ public class ActivityManagerService extends IActivityManager.Stub Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); return; } - mStackSupervisor.findTaskToMoveToFront(task, flags, options, "moveTaskToFront", + ActivityOptions realOptions = options != null + ? options.getOptions(mStackSupervisor) + : null; + mStackSupervisor.findTaskToMoveToFront(task, flags, realOptions, "moveTaskToFront", false /* forceNonResizable */); final ActivityRecord topActivity = task.getTopActivity(); @@ -10546,7 +10771,7 @@ public class ActivityManagerService extends IActivityManager.Stub } finally { Binder.restoreCallingIdentity(origId); } - ActivityOptions.abort(options); + SafeActivityOptions.abort(options); } /** @@ -12245,6 +12470,7 @@ public class ActivityManagerService extends IActivityManager.Stub mConstants.start(mContext.getContentResolver()); mCoreSettingsObserver = new CoreSettingsObserver(this); mFontScaleSettingObserver = new FontScaleSettingObserver(); + GlobalSettingsToPropertiesMapper.start(mContext.getContentResolver()); // Now that the settings provider is published we can consider sending // in a rescue party. @@ -13037,6 +13263,9 @@ public class ActivityManagerService extends IActivityManager.Stub case ActivityManager.BUGREPORT_OPTION_TELEPHONY: extraOptions = "bugreporttelephony"; break; + case ActivityManager.BUGREPORT_OPTION_WIFI: + extraOptions = "bugreportwifi"; + break; default: throw new IllegalArgumentException("Provided bugreport type is not correct, value: " + bugreportType); @@ -13058,9 +13287,8 @@ public class ActivityManagerService extends IActivityManager.Stub * No new code should be calling it. */ @Deprecated - @Override - public void requestTelephonyBugReport(String shareTitle, String shareDescription) { - + private void requestBugReportWithDescription(String shareTitle, String shareDescription, + int bugreportType) { if (!TextUtils.isEmpty(shareTitle)) { if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) { String errorStr = "shareTitle should be less than " + @@ -13089,9 +13317,34 @@ public class ActivityManagerService extends IActivityManager.Stub Slog.d(TAG, "Bugreport notification title " + shareTitle + " description " + shareDescription); - requestBugReport(ActivityManager.BUGREPORT_OPTION_TELEPHONY); + requestBugReport(bugreportType); } + /** + * @deprecated This method is only used by a few internal components and it will soon be + * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps). + * No new code should be calling it. + */ + @Deprecated + @Override + public void requestTelephonyBugReport(String shareTitle, String shareDescription) { + requestBugReportWithDescription(shareTitle, shareDescription, + ActivityManager.BUGREPORT_OPTION_TELEPHONY); + } + + /** + * @deprecated This method is only used by a few internal components and it will soon be + * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps). + * No new code should be calling it. + */ + @Deprecated + @Override + public void requestWifiBugReport(String shareTitle, String shareDescription) { + requestBugReportWithDescription(shareTitle, shareDescription, + ActivityManager.BUGREPORT_OPTION_WIFI); + } + + public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; } @@ -13503,6 +13756,7 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public boolean convertToTranslucent(IBinder token, Bundle options) { + SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(options); final long origId = Binder.clearCallingIdentity(); try { synchronized (this) { @@ -13514,7 +13768,7 @@ public class ActivityManagerService extends IActivityManager.Stub int index = task.mActivities.lastIndexOf(r); if (index > 0) { ActivityRecord under = task.mActivities.get(index - 1); - under.returningOptions = ActivityOptions.fromBundle(options); + under.returningOptions = safeOptions != null ? safeOptions.getOptions(r) : null; } final boolean translucentChanged = r.changeWindowTranslucency(false); if (translucentChanged) { @@ -13659,7 +13913,8 @@ public class ActivityManagerService extends IActivityManager.Stub * not. */ private void enforceSystemHasVrFeature() { - if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) { + if (!mContext.getPackageManager().hasSystemFeature( + PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) { throw new UnsupportedOperationException("VR mode not supported on this device!"); } } @@ -13718,9 +13973,7 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) { - if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) { - throw new UnsupportedOperationException("VR mode not supported on this device!"); - } + enforceSystemHasVrFeature(); final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class); @@ -13752,9 +14005,7 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public boolean isVrModePackageEnabled(ComponentName packageName) { - if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) { - throw new UnsupportedOperationException("VR mode not supported on this device!"); - } + enforceSystemHasVrFeature(); final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class); @@ -13858,68 +14109,100 @@ public class ActivityManagerService extends IActivityManager.Stub Context.WINDOW_SERVICE)).addView(v, lp); } - public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) { - if (sender != null && !(sender instanceof PendingIntentRecord)) { - return; + @Override + public void noteWakeupAlarm(IIntentSender sender, WorkSource workSource, int sourceUid, + String sourcePkg, String tag) { + if (workSource != null && workSource.isEmpty()) { + workSource = null; } - final PendingIntentRecord rec = (PendingIntentRecord)sender; - final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); - synchronized (stats) { - if (mBatteryStatsService.isOnBattery()) { - mBatteryStatsService.enforceCallingPermission(); - int MY_UID = Binder.getCallingUid(); - final int uid; - if (sender == null) { - uid = sourceUid; - } else { - uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid; + + if (sourceUid <= 0 && workSource == null) { + // Try and derive a UID to attribute things to based on the caller. + if (sender != null) { + if (!(sender instanceof PendingIntentRecord)) { + return; } - BatteryStatsImpl.Uid.Pkg pkg = - stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, - sourcePkg != null ? sourcePkg : rec.key.packageName); - pkg.noteWakeupAlarmLocked(tag); - StatsLog.write(StatsLog.WAKEUP_ALARM_OCCURRED, sourceUid >= 0 ? sourceUid : uid, - tag); + + final PendingIntentRecord rec = (PendingIntentRecord) sender; + final int callerUid = Binder.getCallingUid(); + sourceUid = rec.uid == callerUid ? SYSTEM_UID : rec.uid; + } else { + // TODO(narayan): Should we throw an exception in this case ? It means that we + // haven't been able to derive a UID to attribute things to. + return; } } + + if (DEBUG_POWER) { + Slog.w(TAG, "noteWakupAlarm[ sourcePkg=" + sourcePkg + ", sourceUid=" + sourceUid + + ", workSource=" + workSource + ", tag=" + tag + "]"); + } + + mBatteryStatsService.noteWakupAlarm(sourcePkg, sourceUid, workSource, tag); } - public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) { - if (sender != null && !(sender instanceof PendingIntentRecord)) { - return; + @Override + public void noteAlarmStart(IIntentSender sender, WorkSource workSource, int sourceUid, + String tag) { + if (workSource != null && workSource.isEmpty()) { + workSource = null; } - final PendingIntentRecord rec = (PendingIntentRecord)sender; - final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); - synchronized (stats) { - mBatteryStatsService.enforceCallingPermission(); - int MY_UID = Binder.getCallingUid(); - final int uid; - if (sender == null) { - uid = sourceUid; + + if (sourceUid <= 0 && workSource == null) { + // Try and derive a UID to attribute things to based on the caller. + if (sender != null) { + if (!(sender instanceof PendingIntentRecord)) { + return; + } + + final PendingIntentRecord rec = (PendingIntentRecord) sender; + final int callerUid = Binder.getCallingUid(); + sourceUid = rec.uid == callerUid ? SYSTEM_UID : rec.uid; } else { - uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid; + // TODO(narayan): Should we throw an exception in this case ? It means that we + // haven't been able to derive a UID to attribute things to. + return; } - mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid); } + + if (DEBUG_POWER) { + Slog.w(TAG, "noteAlarmStart[sourceUid=" + sourceUid + ", workSource=" + workSource + + ", tag=" + tag + "]"); + } + + mBatteryStatsService.noteAlarmStart(tag, workSource, sourceUid); } - public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) { - if (sender != null && !(sender instanceof PendingIntentRecord)) { - return; + @Override + public void noteAlarmFinish(IIntentSender sender, WorkSource workSource, int sourceUid, + String tag) { + if (workSource != null && workSource.isEmpty()) { + workSource = null; } - final PendingIntentRecord rec = (PendingIntentRecord)sender; - final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); - synchronized (stats) { - mBatteryStatsService.enforceCallingPermission(); - int MY_UID = Binder.getCallingUid(); - final int uid; - if (sender == null) { - uid = sourceUid; + + if (sourceUid <= 0 && workSource == null) { + // Try and derive a UID to attribute things to based on the caller. + if (sender != null) { + if (!(sender instanceof PendingIntentRecord)) { + return; + } + + final PendingIntentRecord rec = (PendingIntentRecord) sender; + final int callerUid = Binder.getCallingUid(); + sourceUid = rec.uid == callerUid ? SYSTEM_UID : rec.uid; } else { - uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid; + // TODO(narayan): Should we throw an exception in this case ? It means that we + // haven't been able to derive a UID to attribute things to. + return; } - mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid); } + + if (DEBUG_POWER) { + Slog.w(TAG, "noteAlarmFinish[sourceUid=" + sourceUid + ", workSource=" + workSource + + ", tag=" + tag + "]"); + } + + mBatteryStatsService.noteAlarmFinish(tag, workSource, sourceUid); } public boolean killPids(int[] pids, String pReason, boolean secure) { @@ -14126,7 +14409,7 @@ public class ActivityManagerService extends IActivityManager.Stub for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { ProcessRecord proc = mLruProcesses.get(i); if (proc.notCachedSinceIdle) { - if (proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE + if (proc.setProcState >= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { if (doKilling && proc.initialIdlePss != 0 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { @@ -14843,6 +15126,7 @@ public class ActivityManagerService extends IActivityManager.Stub (process != null && process.info != null) ? (process.info.isInstantApp() ? 1 : 0) : -1, activity != null ? activity.shortComponentName : null, + activity != null ? activity.packageName : null, process != null ? (process.isInterestingToUserLocked() ? 1 : 0) : -1); // Rate-limit how often we're willing to do the heavy lifting below to @@ -15169,7 +15453,6 @@ public class ActivityManagerService extends IActivityManager.Stub boolean dumpVisibleStacksOnly = false; boolean dumpFocusedStackOnly = false; String dumpPackage = null; - int dumpAppId = -1; int opti = 0; while (opti < args.length) { @@ -15243,6 +15526,15 @@ public class ActivityManagerService extends IActivityManager.Stub } } else if ("service".equals(cmd)) { mServices.writeToProto(proto); + } else if ("processes".equals(cmd) || "p".equals(cmd)) { + if (opti < args.length) { + dumpPackage = args[opti]; + opti++; + } + // output proto is ProcessProto + synchronized (this) { + writeProcessesToProtoLocked(proto, dumpPackage); + } } else { // default option, dump everything, output is ActivityManagerServiceProto synchronized (this) { @@ -15257,6 +15549,10 @@ public class ActivityManagerService extends IActivityManager.Stub long serviceToken = proto.start(ActivityManagerServiceProto.SERVICES); mServices.writeToProto(proto); proto.end(serviceToken); + + long processToken = proto.start(ActivityManagerServiceProto.PROCESSES); + writeProcessesToProtoLocked(proto, dumpPackage); + proto.end(processToken); } } proto.flush(); @@ -15264,16 +15560,7 @@ public class ActivityManagerService extends IActivityManager.Stub return; } - if (dumpPackage != null) { - try { - ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( - dumpPackage, 0); - dumpAppId = UserHandle.getAppId(info.uid); - } catch (NameNotFoundException e) { - e.printStackTrace(); - } - } - + int dumpAppId = getAppId(dumpPackage); boolean more = false; // Is the caller requesting to dump a particular piece of data? if (opti < args.length) { @@ -15315,33 +15602,17 @@ public class ActivityManagerService extends IActivityManager.Stub pw.println(BinderInternal.nGetBinderProxyCount(Integer.parseInt(uid))); } } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { - String[] newArgs; - String name; - if (opti >= args.length) { - name = null; - newArgs = EMPTY_STRING_ARRAY; - } else { + if (opti < args.length) { dumpPackage = args[opti]; opti++; - newArgs = new String[args.length - opti]; - if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, - args.length - opti); } synchronized (this) { dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage); } } else if ("broadcast-stats".equals(cmd)) { - String[] newArgs; - String name; - if (opti >= args.length) { - name = null; - newArgs = EMPTY_STRING_ARRAY; - } else { + if (opti < args.length) { dumpPackage = args[opti]; opti++; - newArgs = new String[args.length - opti]; - if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, - args.length - opti); } synchronized (this) { if (dumpCheckinFormat) { @@ -15352,33 +15623,17 @@ public class ActivityManagerService extends IActivityManager.Stub } } } else if ("intents".equals(cmd) || "i".equals(cmd)) { - String[] newArgs; - String name; - if (opti >= args.length) { - name = null; - newArgs = EMPTY_STRING_ARRAY; - } else { + if (opti < args.length) { dumpPackage = args[opti]; opti++; - newArgs = new String[args.length - opti]; - if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, - args.length - opti); } synchronized (this) { dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage); } } else if ("processes".equals(cmd) || "p".equals(cmd)) { - String[] newArgs; - String name; - if (opti >= args.length) { - name = null; - newArgs = EMPTY_STRING_ARRAY; - } else { + if (opti < args.length) { dumpPackage = args[opti]; opti++; - newArgs = new String[args.length - opti]; - if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, - args.length - opti); } synchronized (this) { dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage, dumpAppId); @@ -15799,8 +16054,21 @@ public class ActivityManagerService extends IActivityManager.Stub } } + private int getAppId(String dumpPackage) { + if (dumpPackage != null) { + try { + ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( + dumpPackage, 0); + return UserHandle.getAppId(info.uid); + } catch (NameNotFoundException e) { + e.printStackTrace(); + } + } + return -1; + } + boolean dumpUids(PrintWriter pw, String dumpPackage, int dumpAppId, SparseArray<UidRecord> uids, - String header, boolean needSep) { + String header, boolean needSep) { boolean printed = false; for (int i=0; i<uids.size(); i++) { UidRecord uidRec = uids.valueAt(i); @@ -16018,7 +16286,7 @@ public class ActivityManagerService extends IActivityManager.Stub "OnHold Norm", "OnHold PERS", dumpPackage); } - needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); + needSep = dumpProcessesToGc(pw, needSep, dumpPackage); needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage); @@ -16303,8 +16571,327 @@ public class ActivityManagerService extends IActivityManager.Stub pw.println(" mForceBackgroundCheck=" + mForceBackgroundCheck); } - boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, - int opti, boolean needSep, boolean dumpAll, String dumpPackage) { + void writeProcessesToProtoLocked(ProtoOutputStream proto, String dumpPackage) { + int numPers = 0; + + final int NP = mProcessNames.getMap().size(); + for (int ip=0; ip<NP; ip++) { + SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); + final int NA = procs.size(); + for (int ia = 0; ia<NA; ia++) { + ProcessRecord r = procs.valueAt(ia); + if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { + continue; + } + r.writeToProto(proto, ProcessesProto.PROCS); + if (r.persistent) { + numPers++; + } + } + } + + for (int i=0; i<mIsolatedProcesses.size(); i++) { + ProcessRecord r = mIsolatedProcesses.valueAt(i); + if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { + continue; + } + r.writeToProto(proto, ProcessesProto.ISOLATED_PROCS); + } + + for (int i=0; i<mActiveInstrumentation.size(); i++) { + ActiveInstrumentation ai = mActiveInstrumentation.get(i); + if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage) + && !ai.mTargetInfo.packageName.equals(dumpPackage)) { + continue; + } + ai.writeToProto(proto, ProcessesProto.ACTIVE_INSTRUMENTATIONS); + } + + int whichAppId = getAppId(dumpPackage); + for (int i=0; i<mActiveUids.size(); i++) { + UidRecord uidRec = mActiveUids.valueAt(i); + if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) { + continue; + } + uidRec.writeToProto(proto, ProcessesProto.ACTIVE_UIDS); + } + + for (int i=0; i<mValidateUids.size(); i++) { + UidRecord uidRec = mValidateUids.valueAt(i); + if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) { + continue; + } + uidRec.writeToProto(proto, ProcessesProto.VALIDATE_UIDS); + } + + if (mLruProcesses.size() > 0) { + long lruToken = proto.start(ProcessesProto.LRU_PROCS); + int total = mLruProcesses.size(); + proto.write(ProcessesProto.LruProcesses.SIZE, total); + proto.write(ProcessesProto.LruProcesses.NON_ACT_AT, total-mLruProcessActivityStart); + proto.write(ProcessesProto.LruProcesses.NON_SVC_AT, total-mLruProcessServiceStart); + writeProcessOomListToProto(proto, ProcessesProto.LruProcesses.LIST, this, + mLruProcesses,false, dumpPackage); + proto.end(lruToken); + } + + if (dumpPackage != null) { + synchronized (mPidsSelfLocked) { + for (int i=0; i<mPidsSelfLocked.size(); i++) { + ProcessRecord r = mPidsSelfLocked.valueAt(i); + if (!r.pkgList.containsKey(dumpPackage)) { + continue; + } + r.writeToProto(proto, ProcessesProto.PIDS_SELF_LOCKED); + } + } + } + + if (mImportantProcesses.size() > 0) { + synchronized (mPidsSelfLocked) { + for (int i=0; i<mImportantProcesses.size(); i++) { + ImportanceToken it = mImportantProcesses.valueAt(i); + ProcessRecord r = mPidsSelfLocked.get(it.pid); + if (dumpPackage != null && (r == null + || !r.pkgList.containsKey(dumpPackage))) { + continue; + } + it.writeToProto(proto, ProcessesProto.IMPORTANT_PROCS); + } + } + } + + for (int i=0; i<mPersistentStartingProcesses.size(); i++) { + ProcessRecord r = mPersistentStartingProcesses.get(i); + if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { + continue; + } + r.writeToProto(proto, ProcessesProto.PERSISTENT_STARTING_PROCS); + } + + for (int i=0; i<mRemovedProcesses.size(); i++) { + ProcessRecord r = mRemovedProcesses.get(i); + if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { + continue; + } + r.writeToProto(proto, ProcessesProto.REMOVED_PROCS); + } + + for (int i=0; i<mProcessesOnHold.size(); i++) { + ProcessRecord r = mProcessesOnHold.get(i); + if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { + continue; + } + r.writeToProto(proto, ProcessesProto.ON_HOLD_PROCS); + } + + writeProcessesToGcToProto(proto, ProcessesProto.GC_PROCS, dumpPackage); + mAppErrors.writeToProto(proto, ProcessesProto.APP_ERRORS, dumpPackage); + + if (dumpPackage == null) { + mUserController.writeToProto(proto, ProcessesProto.USER_CONTROLLER); + getGlobalConfiguration().writeToProto(proto, ProcessesProto.GLOBAL_CONFIGURATION); + proto.write(ProcessesProto.CONFIG_WILL_CHANGE, getFocusedStack().mConfigWillChange); + } + + if (mHomeProcess != null && (dumpPackage == null + || mHomeProcess.pkgList.containsKey(dumpPackage))) { + mHomeProcess.writeToProto(proto, ProcessesProto.HOME_PROC); + } + + if (mPreviousProcess != null && (dumpPackage == null + || mPreviousProcess.pkgList.containsKey(dumpPackage))) { + mPreviousProcess.writeToProto(proto, ProcessesProto.PREVIOUS_PROC); + proto.write(ProcessesProto.PREVIOUS_PROC_VISIBLE_TIME_MS, mPreviousProcessVisibleTime); + } + + if (mHeavyWeightProcess != null && (dumpPackage == null + || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { + mHeavyWeightProcess.writeToProto(proto, ProcessesProto.HEAVY_WEIGHT_PROC); + } + + for (Map.Entry<String, Integer> entry : mCompatModePackages.getPackages().entrySet()) { + String pkg = entry.getKey(); + int mode = entry.getValue(); + if (dumpPackage == null || dumpPackage.equals(pkg)) { + long compatToken = proto.start(ProcessesProto.SCREEN_COMPAT_PACKAGES); + proto.write(ProcessesProto.ScreenCompatPackage.PACKAGE, pkg); + proto.write(ProcessesProto.ScreenCompatPackage.MODE, mode); + proto.end(compatToken); + } + } + + final int NI = mUidObservers.getRegisteredCallbackCount(); + for (int i=0; i<NI; i++) { + final UidObserverRegistration reg = (UidObserverRegistration) + mUidObservers.getRegisteredCallbackCookie(i); + if (dumpPackage == null || dumpPackage.equals(reg.pkg)) { + reg.writeToProto(proto, ProcessesProto.UID_OBSERVERS); + } + } + + for (int v : mDeviceIdleWhitelist) { + proto.write(ProcessesProto.DEVICE_IDLE_WHITELIST, v); + } + + for (int v : mDeviceIdleTempWhitelist) { + proto.write(ProcessesProto.DEVICE_IDLE_TEMP_WHITELIST, v); + } + + if (mPendingTempWhitelist.size() > 0) { + for (int i=0; i < mPendingTempWhitelist.size(); i++) { + mPendingTempWhitelist.valueAt(i).writeToProto(proto, + ProcessesProto.PENDING_TEMP_WHITELIST); + } + } + + if (dumpPackage == null) { + final long sleepToken = proto.start(ProcessesProto.SLEEP_STATUS); + proto.write(ProcessesProto.SleepStatus.WAKEFULNESS, + PowerManagerInternal.wakefulnessToProtoEnum(mWakefulness)); + for (SleepToken st : mStackSupervisor.mSleepTokens) { + proto.write(ProcessesProto.SleepStatus.SLEEP_TOKENS, st.toString()); + } + proto.write(ProcessesProto.SleepStatus.SLEEPING, mSleeping); + proto.write(ProcessesProto.SleepStatus.SHUTTING_DOWN, mShuttingDown); + proto.write(ProcessesProto.SleepStatus.TEST_PSS_MODE, mTestPssMode); + proto.end(sleepToken); + + if (mRunningVoice != null) { + final long vrToken = proto.start(ProcessesProto.RUNNING_VOICE); + proto.write(ProcessesProto.VoiceProto.SESSION, mRunningVoice.toString()); + mVoiceWakeLock.writeToProto(proto, ProcessesProto.VoiceProto.WAKELOCK); + proto.end(vrToken); + } + + mVrController.writeToProto(proto, ProcessesProto.VR_CONTROLLER); + } + + if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient + || mOrigWaitForDebugger) { + if (dumpPackage == null || dumpPackage.equals(mDebugApp) + || dumpPackage.equals(mOrigDebugApp)) { + final long debugAppToken = proto.start(ProcessesProto.DEBUG); + proto.write(ProcessesProto.DebugApp.DEBUG_APP, mDebugApp); + proto.write(ProcessesProto.DebugApp.ORIG_DEBUG_APP, mOrigDebugApp); + proto.write(ProcessesProto.DebugApp.DEBUG_TRANSIENT, mDebugTransient); + proto.write(ProcessesProto.DebugApp.ORIG_WAIT_FOR_DEBUGGER, mOrigWaitForDebugger); + proto.end(debugAppToken); + } + } + + if (mCurAppTimeTracker != null) { + mCurAppTimeTracker.writeToProto(proto, ProcessesProto.CURRENT_TRACKER, true); + } + + if (mMemWatchProcesses.getMap().size() > 0) { + final long token = proto.start(ProcessesProto.MEM_WATCH_PROCESSES); + ArrayMap<String, SparseArray<Pair<Long, String>>> procs = mMemWatchProcesses.getMap(); + for (int i=0; i<procs.size(); i++) { + final String proc = procs.keyAt(i); + final SparseArray<Pair<Long, String>> uids = procs.valueAt(i); + final long ptoken = proto.start(ProcessesProto.MemWatchProcess.PROCS); + proto.write(ProcessesProto.MemWatchProcess.Process.NAME, proc); + for (int j=0; j<uids.size(); j++) { + final long utoken = proto.start(ProcessesProto.MemWatchProcess.Process.MEM_STATS); + Pair<Long, String> val = uids.valueAt(j); + proto.write(ProcessesProto.MemWatchProcess.Process.MemStats.UID, uids.keyAt(j)); + proto.write(ProcessesProto.MemWatchProcess.Process.MemStats.SIZE, + DebugUtils.sizeValueToString(val.first, new StringBuilder())); + proto.write(ProcessesProto.MemWatchProcess.Process.MemStats.REPORT_TO, val.second); + proto.end(utoken); + } + proto.end(ptoken); + } + + final long dtoken = proto.start(ProcessesProto.MemWatchProcess.DUMP); + proto.write(ProcessesProto.MemWatchProcess.Dump.PROC_NAME, mMemWatchDumpProcName); + proto.write(ProcessesProto.MemWatchProcess.Dump.FILE, mMemWatchDumpFile); + proto.write(ProcessesProto.MemWatchProcess.Dump.PID, mMemWatchDumpPid); + proto.write(ProcessesProto.MemWatchProcess.Dump.UID, mMemWatchDumpUid); + proto.end(dtoken); + + proto.end(token); + } + + if (mTrackAllocationApp != null) { + if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) { + proto.write(ProcessesProto.TRACK_ALLOCATION_APP, mTrackAllocationApp); + } + } + + if (mProfileApp != null || mProfileProc != null || (mProfilerInfo != null && + (mProfilerInfo.profileFile != null || mProfilerInfo.profileFd != null))) { + if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { + final long token = proto.start(ProcessesProto.PROFILE); + proto.write(ProcessesProto.Profile.APP_NAME, mProfileApp); + mProfileProc.writeToProto(proto,ProcessesProto.Profile.PROC); + if (mProfilerInfo != null) { + mProfilerInfo.writeToProto(proto, ProcessesProto.Profile.INFO); + proto.write(ProcessesProto.Profile.TYPE, mProfileType); + } + proto.end(token); + } + } + + if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) { + proto.write(ProcessesProto.NATIVE_DEBUGGING_APP, mNativeDebuggingApp); + } + + if (dumpPackage == null) { + proto.write(ProcessesProto.ALWAYS_FINISH_ACTIVITIES, mAlwaysFinishActivities); + if (mController != null) { + final long token = proto.start(ProcessesProto.CONTROLLER); + proto.write(ProcessesProto.Controller.CONTROLLER, mController.toString()); + proto.write(ProcessesProto.Controller.IS_A_MONKEY, mControllerIsAMonkey); + proto.end(token); + } + proto.write(ProcessesProto.TOTAL_PERSISTENT_PROCS, numPers); + proto.write(ProcessesProto.PROCESSES_READY, mProcessesReady); + proto.write(ProcessesProto.SYSTEM_READY, mSystemReady); + proto.write(ProcessesProto.BOOTED, mBooted); + proto.write(ProcessesProto.FACTORY_TEST, mFactoryTest); + proto.write(ProcessesProto.BOOTING, mBooting); + proto.write(ProcessesProto.CALL_FINISH_BOOTING, mCallFinishBooting); + proto.write(ProcessesProto.BOOT_ANIMATION_COMPLETE, mBootAnimationComplete); + proto.write(ProcessesProto.LAST_POWER_CHECK_UPTIME_MS, mLastPowerCheckUptime); + mStackSupervisor.mGoingToSleep.writeToProto(proto, ProcessesProto.GOING_TO_SLEEP); + mStackSupervisor.mLaunchingActivity.writeToProto(proto, ProcessesProto.LAUNCHING_ACTIVITY); + proto.write(ProcessesProto.ADJ_SEQ, mAdjSeq); + proto.write(ProcessesProto.LRU_SEQ, mLruSeq); + proto.write(ProcessesProto.NUM_NON_CACHED_PROCS, mNumNonCachedProcs); + proto.write(ProcessesProto.NUM_SERVICE_PROCS, mNumServiceProcs); + proto.write(ProcessesProto.NEW_NUM_SERVICE_PROCS, mNewNumServiceProcs); + proto.write(ProcessesProto.ALLOW_LOWER_MEM_LEVEL, mAllowLowerMemLevel); + proto.write(ProcessesProto.LAST_MEMORY_LEVEL, mLastMemoryLevel); + proto.write(ProcessesProto.LAST_NUM_PROCESSES, mLastNumProcesses); + long now = SystemClock.uptimeMillis(); + ProtoUtils.toDuration(proto, ProcessesProto.LAST_IDLE_TIME, mLastIdleTime, now); + proto.write(ProcessesProto.LOW_RAM_SINCE_LAST_IDLE_MS, getLowRamTimeSinceIdle(now)); + } + + } + + void writeProcessesToGcToProto(ProtoOutputStream proto, long fieldId, String dumpPackage) { + if (mProcessesToGc.size() > 0) { + long now = SystemClock.uptimeMillis(); + for (int i=0; i<mProcessesToGc.size(); i++) { + ProcessRecord r = mProcessesToGc.get(i); + if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { + continue; + } + final long token = proto.start(fieldId); + r.writeToProto(proto, ProcessToGcProto.PROC); + proto.write(ProcessToGcProto.REPORT_LOW_MEMORY, r.reportLowMemory); + proto.write(ProcessToGcProto.NOW_UPTIME_MS, now); + proto.write(ProcessToGcProto.LAST_GCED_MS, r.lastRequestedGc); + proto.write(ProcessToGcProto.LAST_LOW_MEMORY_MS, r.lastLowMemory); + proto.end(token); + } + } + } + + boolean dumpProcessesToGc(PrintWriter pw, boolean needSep, String dumpPackage) { if (mProcessesToGc.size() > 0) { boolean printed = false; long now = SystemClock.uptimeMillis(); @@ -16382,7 +16969,7 @@ public class ActivityManagerService extends IActivityManager.Stub needSep = true; } - dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); + dumpProcessesToGc(pw, needSep, null); pw.println(); pw.println(" mHomeProcess: " + mHomeProcess); @@ -16933,11 +17520,8 @@ public class ActivityManagerService extends IActivityManager.Stub return numPers; } - private static final boolean dumpProcessOomList(PrintWriter pw, - ActivityManagerService service, List<ProcessRecord> origList, - String prefix, String normalLabel, String persistentLabel, - boolean inclDetails, String dumpPackage) { - + private static final ArrayList<Pair<ProcessRecord, Integer>> + sortProcessOomList(List<ProcessRecord> origList, String dumpPackage) { ArrayList<Pair<ProcessRecord, Integer>> list = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); for (int i=0; i<origList.size(); i++) { @@ -16948,10 +17532,6 @@ public class ActivityManagerService extends IActivityManager.Stub list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); } - if (list.size() <= 0) { - return false; - } - Comparator<Pair<ProcessRecord, Integer>> comparator = new Comparator<Pair<ProcessRecord, Integer>>() { @Override @@ -16971,6 +17551,113 @@ public class ActivityManagerService extends IActivityManager.Stub }; Collections.sort(list, comparator); + return list; + } + + private static final boolean writeProcessOomListToProto(ProtoOutputStream proto, long fieldId, + ActivityManagerService service, List<ProcessRecord> origList, + boolean inclDetails, String dumpPackage) { + ArrayList<Pair<ProcessRecord, Integer>> list = sortProcessOomList(origList, dumpPackage); + if (list.isEmpty()) return false; + + final long curUptime = SystemClock.uptimeMillis(); + + for (int i = list.size() - 1; i >= 0; i--) { + ProcessRecord r = list.get(i).first; + long token = proto.start(fieldId); + String oomAdj = ProcessList.makeOomAdjString(r.setAdj); + proto.write(ProcessOomProto.PERSISTENT, r.persistent); + proto.write(ProcessOomProto.NUM, (origList.size()-1)-list.get(i).second); + proto.write(ProcessOomProto.OOM_ADJ, oomAdj); + int schedGroup = ProcessOomProto.SCHED_GROUP_UNKNOWN; + switch (r.setSchedGroup) { + case ProcessList.SCHED_GROUP_BACKGROUND: + schedGroup = ProcessOomProto.SCHED_GROUP_BACKGROUND; + break; + case ProcessList.SCHED_GROUP_DEFAULT: + schedGroup = ProcessOomProto.SCHED_GROUP_DEFAULT; + break; + case ProcessList.SCHED_GROUP_TOP_APP: + schedGroup = ProcessOomProto.SCHED_GROUP_TOP_APP; + break; + case ProcessList.SCHED_GROUP_TOP_APP_BOUND: + schedGroup = ProcessOomProto.SCHED_GROUP_TOP_APP_BOUND; + break; + } + if (schedGroup != ProcessOomProto.SCHED_GROUP_UNKNOWN) { + proto.write(ProcessOomProto.SCHED_GROUP, schedGroup); + } + if (r.foregroundActivities) { + proto.write(ProcessOomProto.ACTIVITIES, true); + } else if (r.foregroundServices) { + proto.write(ProcessOomProto.SERVICES, true); + } + proto.write(ProcessOomProto.STATE, ProcessList.makeProcStateProtoEnum(r.curProcState)); + proto.write(ProcessOomProto.TRIM_MEMORY_LEVEL, r.trimMemoryLevel); + r.writeToProto(proto, ProcessOomProto.PROC); + proto.write(ProcessOomProto.ADJ_TYPE, r.adjType); + if (r.adjSource != null || r.adjTarget != null) { + if (r.adjTarget instanceof ComponentName) { + ComponentName cn = (ComponentName) r.adjTarget; + cn.writeToProto(proto, ProcessOomProto.ADJ_TARGET_COMPONENT_NAME); + } else if (r.adjTarget != null) { + proto.write(ProcessOomProto.ADJ_TARGET_OBJECT, r.adjTarget.toString()); + } + if (r.adjSource instanceof ProcessRecord) { + ProcessRecord p = (ProcessRecord) r.adjSource; + p.writeToProto(proto, ProcessOomProto.ADJ_SOURCE_PROC); + } else if (r.adjSource != null) { + proto.write(ProcessOomProto.ADJ_SOURCE_OBJECT, r.adjSource.toString()); + } + } + if (inclDetails) { + long detailToken = proto.start(ProcessOomProto.DETAIL); + proto.write(ProcessOomProto.Detail.MAX_ADJ, r.maxAdj); + proto.write(ProcessOomProto.Detail.CUR_RAW_ADJ, r.curRawAdj); + proto.write(ProcessOomProto.Detail.SET_RAW_ADJ, r.setRawAdj); + proto.write(ProcessOomProto.Detail.CUR_ADJ, r.curAdj); + proto.write(ProcessOomProto.Detail.SET_ADJ, r.setAdj); + proto.write(ProcessOomProto.Detail.CURRENT_STATE, + ProcessList.makeProcStateProtoEnum(r.curProcState)); + proto.write(ProcessOomProto.Detail.SET_STATE, + ProcessList.makeProcStateProtoEnum(r.setProcState)); + proto.write(ProcessOomProto.Detail.LAST_PSS, DebugUtils.sizeValueToString( + r.lastPss*1024, new StringBuilder())); + proto.write(ProcessOomProto.Detail.LAST_SWAP_PSS, DebugUtils.sizeValueToString( + r.lastSwapPss*1024, new StringBuilder())); + proto.write(ProcessOomProto.Detail.LAST_CACHED_PSS, DebugUtils.sizeValueToString( + r.lastCachedPss*1024, new StringBuilder())); + proto.write(ProcessOomProto.Detail.CACHED, r.cached); + proto.write(ProcessOomProto.Detail.EMPTY, r.empty); + proto.write(ProcessOomProto.Detail.HAS_ABOVE_CLIENT, r.hasAboveClient); + + if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { + if (r.lastCpuTime != 0) { + long uptimeSince = curUptime - service.mLastPowerCheckUptime; + long timeUsed = r.curCpuTime - r.lastCpuTime; + long cpuTimeToken = proto.start(ProcessOomProto.Detail.SERVICE_RUN_TIME); + proto.write(ProcessOomProto.Detail.CpuRunTime.OVER_MS, uptimeSince); + proto.write(ProcessOomProto.Detail.CpuRunTime.USED_MS, timeUsed); + proto.write(ProcessOomProto.Detail.CpuRunTime.ULTILIZATION, + (100.0*timeUsed)/uptimeSince); + proto.end(cpuTimeToken); + } + } + proto.end(detailToken); + } + proto.end(token); + } + + return true; + } + + private static final boolean dumpProcessOomList(PrintWriter pw, + ActivityManagerService service, List<ProcessRecord> origList, + String prefix, String normalLabel, String persistentLabel, + boolean inclDetails, String dumpPackage) { + + ArrayList<Pair<ProcessRecord, Integer>> list = sortProcessOomList(origList, dumpPackage); + if (list.isEmpty()) return false; final long curUptime = SystemClock.uptimeMillis(); final long uptimeSince = curUptime - service.mLastPowerCheckUptime; @@ -17627,11 +18314,20 @@ public class ActivityManagerService extends IActivityManager.Stub if (mi == null) { mi = new Debug.MemoryInfo(); } + final int reportType; + final long startTime; + final long endTime; if (opts.dumpDetails || (!brief && !opts.oomOnly)) { + reportType = ProcessStats.ADD_PSS_EXTERNAL_SLOW; + startTime = SystemClock.currentThreadTimeMillis(); Debug.getMemoryInfo(pid, mi); + endTime = SystemClock.currentThreadTimeMillis(); hasSwapPss = mi.hasSwappedOutPss; } else { + reportType = ProcessStats.ADD_PSS_EXTERNAL; + startTime = SystemClock.currentThreadTimeMillis(); mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null); + endTime = SystemClock.currentThreadTimeMillis(); mi.dalvikPrivateDirty = (int)tmpLong[0]; } if (opts.dumpDetails) { @@ -17674,7 +18370,8 @@ public class ActivityManagerService extends IActivityManager.Stub synchronized (this) { if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { // Record this for posterity if the process has been stable. - r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); + r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, + reportType, endTime-startTime, r.pkgList); } } @@ -18117,11 +18814,20 @@ public class ActivityManagerService extends IActivityManager.Stub if (mi == null) { mi = new Debug.MemoryInfo(); } + final int reportType; + final long startTime; + final long endTime; if (opts.dumpDetails || (!brief && !opts.oomOnly)) { + reportType = ProcessStats.ADD_PSS_EXTERNAL_SLOW; + startTime = SystemClock.currentThreadTimeMillis(); Debug.getMemoryInfo(pid, mi); + endTime = SystemClock.currentThreadTimeMillis(); hasSwapPss = mi.hasSwappedOutPss; } else { + reportType = ProcessStats.ADD_PSS_EXTERNAL; + startTime = SystemClock.currentThreadTimeMillis(); mi.dalvikPss = (int) Debug.getPss(pid, tmpLong, null); + endTime = SystemClock.currentThreadTimeMillis(); mi.dalvikPrivateDirty = (int) tmpLong[0]; } if (opts.dumpDetails) { @@ -18160,7 +18866,8 @@ public class ActivityManagerService extends IActivityManager.Stub synchronized (this) { if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { // Record this for posterity if the process has been stable. - r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); + r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, + reportType, endTime-startTime, r.pkgList); } } @@ -21350,7 +22057,7 @@ public class ActivityManagerService extends IActivityManager.Stub mAppWarnings.onDensityChanged(); killAllBackgroundProcessesExcept(N, - ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE); + ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE); } } @@ -21401,6 +22108,17 @@ public class ActivityManagerService extends IActivityManager.Stub private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) { final Rect newStackBounds = new Rect(); final ActivityStack stack = mStackSupervisor.getStack(stackId); + + // TODO(b/71548119): Revert CL introducing below once cause of mismatch is found. + if (stack == null) { + final StringWriter writer = new StringWriter(); + final PrintWriter printWriter = new PrintWriter(writer); + mStackSupervisor.dumpDisplays(printWriter); + printWriter.flush(); + + Log.wtf(TAG, "stack not found:" + stackId + " displays:" + writer); + } + stack.getBoundsForNewConfiguration(newStackBounds); mStackSupervisor.resizeStackLocked( stack, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */, @@ -22324,6 +23042,7 @@ public class ActivityManagerService extends IActivityManager.Stub // to the top state. switch (procState) { case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE: + case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE: // Something else is keeping it at this level, just leave it. break; case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: @@ -22422,11 +23141,12 @@ public class ActivityManagerService extends IActivityManager.Stub * Record new PSS sample for a process. */ void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss, - long now) { + long pssDuration, long now) { EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024, swapPss * 1024); proc.lastPssTime = now; - proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList); + proc.baseProcessTracker.addPss(pss, uss, true, ProcessStats.ADD_PSS_INTERNAL, + pssDuration, proc.pkgList); if (DEBUG_PSS) Slog.d(TAG_PSS, "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss + " state=" + ProcessList.makeProcStateString(procState)); @@ -22921,8 +23641,11 @@ public class ActivityManagerService extends IActivityManager.Stub // the data right when a process is transitioning between process // states, which well tend to give noisy data. long start = SystemClock.uptimeMillis(); + long startTime = SystemClock.currentThreadTimeMillis(); long pss = Debug.getPss(app.pid, mTmpLong, null); - recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now); + long endTime = SystemClock.currentThreadTimeMillis(); + recordPssSampleLocked(app, app.curProcState, pss, endTime-startTime, + mTmpLong[0], mTmpLong[1], now); mPendingPssProcesses.remove(app); Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState + " to " + app.curProcState + ": " @@ -23157,7 +23880,7 @@ public class ActivityManagerService extends IActivityManager.Stub // To avoid some abuse patterns, we are going to be careful about what we consider // to be an app interaction. Being the top activity doesn't count while the display // is sleeping, nor do short foreground services. - if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) { + if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP) { isInteraction = true; app.fgInteractionTime = 0; } else if (app.curProcState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) { @@ -24002,7 +24725,7 @@ public class ActivityManagerService extends IActivityManager.Stub final int size = mActiveUids.size(); for (int i = 0; i < size; i++) { final int uid = mActiveUids.keyAt(i); - if (!UserHandle.isApp(uid)) { + if (UserHandle.isCore(uid)) { continue; } final UidRecord uidRec = mActiveUids.valueAt(i); @@ -24674,6 +25397,7 @@ public class ActivityManagerService extends IActivityManager.Stub ActivityManagerService.this.onUserStoppedLocked(userId); } mBatteryStatsService.onUserRemoved(userId); + mUserController.onUserRemoved(userId); } @Override @@ -24802,16 +25526,20 @@ public class ActivityManagerService extends IActivityManager.Stub // "= 0" is needed because otherwise catch(RemoteException) would make it look like // packageUid may not be initialized. int packageUid = 0; + final long ident = Binder.clearCallingIdentity(); try { packageUid = AppGlobals.getPackageManager().getPackageUid( packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId); } catch (RemoteException e) { // Shouldn't happen. + } finally { + Binder.restoreCallingIdentity(ident); } synchronized (ActivityManagerService.this) { return mActivityStartController.startActivitiesInPackage(packageUid, packageName, - intents, resolvedTypes, /*resultTo*/ null, bOptions, userId); + intents, resolvedTypes, null /* resultTo */, + SafeActivityOptions.fromBundle(bOptions), userId); } } @@ -25054,6 +25782,30 @@ public class ActivityManagerService extends IActivityManager.Stub public void registerScreenObserver(ScreenObserver observer) { mScreenObservers.add(observer); } + + @Override + public boolean canStartMoreUsers() { + return mUserController.canStartMoreUsers(); + } + + @Override + public void setSwitchingFromSystemUserMessage(String switchingFromSystemUserMessage) { + mUserController.setSwitchingFromSystemUserMessage(switchingFromSystemUserMessage); + } + + @Override + public void setSwitchingToSystemUserMessage(String switchingToSystemUserMessage) { + mUserController.setSwitchingToSystemUserMessage(switchingToSystemUserMessage); + } + + @Override + public int getMaxRunningUsers() { + return mUserController.mMaxRunningUsers; + } + + public boolean isCallerRecents(int callingUid) { + return getRecentTasks().isCallerRecents(callingUid); + } } /** @@ -25201,11 +25953,15 @@ public class ActivityManagerService extends IActivityManager.Stub } @Override - public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback) - throws RemoteException { + public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback, + CharSequence message) throws RemoteException { + if (message != null) { + enforceCallingPermission(permission.SHOW_KEYGUARD_MESSAGE, + "dismissKeyguard()"); + } final long callingId = Binder.clearCallingIdentity(); try { - mKeyguardController.dismissKeyguard(token, callback); + mKeyguardController.dismissKeyguard(token, callback, message); } finally { Binder.restoreCallingIdentity(callingId); } @@ -25260,6 +26016,19 @@ public class ActivityManagerService extends IActivityManager.Stub } } } + if (updateFrameworkRes) { + // Update system server components that need to know about changed overlays. Because the + // overlay is applied in ActivityThread, we need to serialize through its thread too. + final Executor executor = ActivityThread.currentActivityThread().getExecutor(); + final DisplayManagerInternal display = + LocalServices.getService(DisplayManagerInternal.class); + if (display != null) { + executor.execute(display::onOverlayChanged); + } + if (mWindowManager != null) { + executor.execute(mWindowManager::onOverlayChanged); + } + } } /** @@ -25350,4 +26119,23 @@ public class ActivityManagerService extends IActivityManager.Stub } } } + + @Override + public void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition) + throws RemoteException { + enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS, + "registerRemoteAnimations"); + synchronized (this) { + final ActivityRecord r = ActivityRecord.isInStackLocked(token); + if (r == null) { + return; + } + final long origId = Binder.clearCallingIdentity(); + try { + r.registerRemoteAnimations(definition); + } finally { + Binder.restoreCallingIdentity(origId); + } + } + } } |