void resetProcessCrashTimeLocked(boolean resetEntireUser, int appId, int userId) { final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); for (int ip = pmap.size() - 1; ip >= 0; ip--) { SparseArray<Long> ba = pmap.valueAt(ip); for (int i = ba.size() - 1; i >= 0; i--) { boolean remove = false; final int entUid = ba.keyAt(i); if (!resetEntireUser) { if (userId == UserHandle.USER_ALL) { if (UserHandle.getAppId(entUid) == appId) { remove = true; } } else { if (entUid == UserHandle.getUid(userId, appId)) { remove = true; } } } else if (UserHandle.getUserId(entUid) == userId) { remove = true; } if (remove) { ba.removeAt(i); } } if (ba.size() == 0) { pmap.removeAt(ip); } } }
final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) { if (r.nextReceiver > 0) { Object curReceiver = r.receivers.get(r.nextReceiver - 1); if (curReceiver instanceof BroadcastFilter) { BroadcastFilter bf = (BroadcastFilter) curReceiver; EventLog.writeEvent( EventLogTags.AM_BROADCAST_DISCARD_FILTER, bf.owningUserId, System.identityHashCode(r), r.intent.getAction(), r.nextReceiver - 1, System.identityHashCode(bf)); } else { ResolveInfo ri = (ResolveInfo) curReceiver; EventLog.writeEvent( EventLogTags.AM_BROADCAST_DISCARD_APP, UserHandle.getUserId(ri.activityInfo.applicationInfo.uid), System.identityHashCode(r), r.intent.getAction(), r.nextReceiver - 1, ri.toString()); } } else { Slog.w(TAG, "Discarding broadcast before first receiver is invoked: " + r); EventLog.writeEvent( EventLogTags.AM_BROADCAST_DISCARD_APP, -1, System.identityHashCode(r), r.intent.getAction(), r.nextReceiver, "NONE"); } }
boolean updateService(Context context, ActivityManager.RunningServiceInfo service) { final PackageManager pm = context.getPackageManager(); boolean changed = false; ServiceItem si = mServices.get(service.service); if (si == null) { changed = true; si = new ServiceItem(mUserId); si.mRunningService = service; try { si.mServiceInfo = ActivityThread.getPackageManager() .getServiceInfo( service.service, PackageManager.GET_UNINSTALLED_PACKAGES, UserHandle.getUserId(service.uid)); if (si.mServiceInfo == null) { Log.d("RunningService", "getServiceInfo returned null for: " + service.service); return false; } } catch (RemoteException e) { } si.mDisplayLabel = makeLabel(pm, si.mRunningService.service.getClassName(), si.mServiceInfo); mLabel = mDisplayLabel != null ? mDisplayLabel.toString() : null; si.mPackageInfo = si.mServiceInfo.applicationInfo; mServices.put(service.service, si); } si.mCurSeq = mCurSeq; si.mRunningService = service; long activeSince = service.restarting == 0 ? service.activeSince : -1; if (si.mActiveSince != activeSince) { si.mActiveSince = activeSince; changed = true; } if (service.clientPackage != null && service.clientLabel != 0) { if (si.mShownAsStarted) { si.mShownAsStarted = false; changed = true; } try { Resources clientr = pm.getResourcesForApplication(service.clientPackage); String label = clientr.getString(service.clientLabel); si.mDescription = context.getResources().getString(R.string.service_client_name, label); } catch (PackageManager.NameNotFoundException e) { si.mDescription = null; } } else { if (!si.mShownAsStarted) { si.mShownAsStarted = true; changed = true; } si.mDescription = context.getResources().getString(R.string.service_started_by_app); } return changed; }
/** * Return the user handle of the application that created this PendingIntent, that is the user * under which you will actually be sending the Intent. The returned UserHandle is supplied by the * system, so that an application can not spoof its user. See {@link * android.os.Process#myUserHandle() Process.myUserHandle()} for more explanation of user handles. * * <p class="note">Be careful about how you use this. All this tells you is who created the * PendingIntent. It does <strong>not</strong> tell you who handed the PendingIntent to you: that * is, PendingIntent objects are intended to be passed between applications, so the PendingIntent * you receive from an application could actually be one it received from another application, * meaning the result you get here will identify the original application. Because of this, you * should only use this information to identify who you expect to be interacting with through a * {@link #send} call, not who gave you the PendingIntent. * * @return The user handle of the PendingIntent, or null if there is none associated with it. */ @Nullable public UserHandle getCreatorUserHandle() { try { int uid = ActivityManagerNative.getDefault().getUidForIntentSender(mTarget); return uid > 0 ? new UserHandle(UserHandle.getUserId(uid)) : null; } catch (RemoteException e) { // Should never happen. return null; } }
@Override public void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == INSTALLED_APP_DETAILS && mCurrentPkgName != null) { if (mListType == LIST_TYPE_NOTIFICATION) { mApplications.mExtraInfoBridge.forceUpdate(mCurrentPkgName, mCurrentUid); } else if (mListType == LIST_TYPE_HIGH_POWER || mListType == LIST_TYPE_OVERLAY || mListType == LIST_TYPE_WRITE_SETTINGS) { if (mFinishAfterDialog) { getActivity().onBackPressed(); } else { mApplications.mExtraInfoBridge.forceUpdate(mCurrentPkgName, mCurrentUid); } } else { mApplicationsState.requestSize(mCurrentPkgName, UserHandle.getUserId(mCurrentUid)); } } }
public String getSavedNetworkSummary() { if (mConfig != null) { PackageManager pm = mContext.getPackageManager(); String systemName = pm.getNameForUid(android.os.Process.SYSTEM_UID); int userId = UserHandle.getUserId(mConfig.creatorUid); ApplicationInfo appInfo = null; if (mConfig.creatorName != null && mConfig.creatorName.equals(systemName)) { appInfo = mContext.getApplicationInfo(); } else { try { IPackageManager ipm = AppGlobals.getPackageManager(); appInfo = ipm.getApplicationInfo(mConfig.creatorName, 0 /* flags */, userId); } catch (RemoteException rex) { } } if (appInfo != null && !appInfo.packageName.equals(mContext.getString(R.string.settings_package)) && !appInfo.packageName.equals(mContext.getString(R.string.certinstaller_package))) { return mContext.getString(R.string.saved_network, appInfo.loadLabel(pm)); } } return ""; }
final void processNextBroadcast(boolean fromMsg) { synchronized (mService) { BroadcastRecord r; if (DEBUG_BROADCAST) Slog.v( TAG, "processNextBroadcast [" + mQueueName + "]: " + mParallelBroadcasts.size() + " broadcasts, " + mOrderedBroadcasts.size() + " ordered broadcasts"); mService.updateCpuStats(); if (fromMsg) { mBroadcastsScheduled = false; } // First, deliver any non-serialized broadcasts right away. while (mParallelBroadcasts.size() > 0) { r = mParallelBroadcasts.remove(0); r.dispatchTime = SystemClock.uptimeMillis(); r.dispatchClockTime = System.currentTimeMillis(); mCurrentBroadcast = r; final int N = r.receivers.size(); if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast [" + mQueueName + "] " + r); for (int i = 0; i < N; i++) { Object target = r.receivers.get(i); if (DEBUG_BROADCAST) Slog.v( TAG, "Delivering non-ordered on [" + mQueueName + "] to registered " + target + ": " + r); deliverToRegisteredReceiverLocked(r, (BroadcastFilter) target, false); } addBroadcastToHistoryLocked(r); mCurrentBroadcast = null; if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast [" + mQueueName + "] " + r); } // Now take care of the next serialized one... // If we are waiting for a process to come up to handle the next // broadcast, then do nothing at this point. Just in case, we // check that the process we're waiting for still exists. if (mPendingBroadcast != null) { if (DEBUG_BROADCAST_LIGHT) { Slog.v( TAG, "processNextBroadcast [" + mQueueName + "]: waiting for " + mPendingBroadcast.curApp); } boolean isDead; synchronized (mService.mPidsSelfLocked) { isDead = (mService.mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null); } if (!isDead) { // It's still alive, so keep waiting return; } else { Slog.w( TAG, "pending app [" + mQueueName + "]" + mPendingBroadcast.curApp + " died before responding to broadcast"); mPendingBroadcast.state = BroadcastRecord.IDLE; mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex; mPendingBroadcast = null; } } boolean looped = false; do { if (mOrderedBroadcasts.size() == 0) { // No more broadcasts pending, so all done! mService.scheduleAppGcsLocked(); if (looped) { // If we had finished the last ordered broadcast, then // make sure all processes have correct oom and sched // adjustments. mService.updateOomAdjLocked(); } return; } r = mOrderedBroadcasts.get(0); mCurrentBroadcast = r; boolean forceReceive = false; // Ensure that even if something goes awry with the timeout // detection, we catch "hung" broadcasts here, discard them, // and continue to make progress. // // This is only done if the system is ready so that PRE_BOOT_COMPLETED // receivers don't get executed with timeouts. They're intended for // one time heavy lifting after system upgrades and can take // significant amounts of time. int numReceivers = (r.receivers != null) ? r.receivers.size() : 0; if (mService.mProcessesReady && r.dispatchTime > 0) { long now = SystemClock.uptimeMillis(); if ((numReceivers > 0) && (now > r.dispatchTime + (2 * mTimeoutPeriod * numReceivers))) { Slog.w( TAG, "Hung broadcast [" + mQueueName + "] discarded after timeout failure:" + " now=" + now + " dispatchTime=" + r.dispatchTime + " startTime=" + r.receiverTime + " intent=" + r.intent + " numReceivers=" + numReceivers + " nextReceiver=" + r.nextReceiver + " state=" + r.state); broadcastTimeoutLocked(false); // forcibly finish this broadcast forceReceive = true; r.state = BroadcastRecord.IDLE; } } if (r.state != BroadcastRecord.IDLE) { if (DEBUG_BROADCAST) Slog.d( TAG, "processNextBroadcast(" + mQueueName + ") called when not idle (state=" + r.state + ")"); return; } if (r.receivers == null || r.nextReceiver >= numReceivers || r.resultAbort || forceReceive) { // No more receivers for this broadcast! Send the final // result if requested... if (r.resultTo != null) { try { if (DEBUG_BROADCAST) { int seq = r.intent.getIntExtra("seq", -1); Slog.i( TAG, "Finishing broadcast [" + mQueueName + "] " + r.intent.getAction() + " seq=" + seq + " app=" + r.callerApp); } performReceiveLocked( r.callerApp, r.resultTo, new Intent(r.intent), r.resultCode, r.resultData, r.resultExtras, false, false, r.userId); // Set this to null so that the reference // (local and remote) isnt kept in the mBroadcastHistory. r.resultTo = null; } catch (RemoteException e) { Slog.w( TAG, "Failure [" + mQueueName + "] sending broadcast result of " + r.intent, e); } } if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG"); cancelBroadcastTimeoutLocked(); if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast " + r); // ... and on to the next... addBroadcastToHistoryLocked(r); mOrderedBroadcasts.remove(0); mCurrentBroadcast = null; r = null; looped = true; continue; } } while (r == null); // Get the next receiver... int recIdx = r.nextReceiver++; // Keep track of when this receiver started, and make sure there // is a timeout message pending to kill it if need be. r.receiverTime = SystemClock.uptimeMillis(); if (recIdx == 0) { r.dispatchTime = r.receiverTime; r.dispatchClockTime = System.currentTimeMillis(); if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast [" + mQueueName + "] " + r); } if (!mPendingBroadcastTimeoutMessage) { long timeoutTime = r.receiverTime + mTimeoutPeriod; if (DEBUG_BROADCAST) Slog.v( TAG, "Submitting BROADCAST_TIMEOUT_MSG [" + mQueueName + "] for " + r + " at " + timeoutTime); setBroadcastTimeoutLocked(timeoutTime); } Object nextReceiver = r.receivers.get(recIdx); if (nextReceiver instanceof BroadcastFilter) { // Simple case: this is a registered receiver who gets // a direct call. BroadcastFilter filter = (BroadcastFilter) nextReceiver; if (DEBUG_BROADCAST) Slog.v(TAG, "Delivering ordered [" + mQueueName + "] to registered " + filter + ": " + r); deliverToRegisteredReceiverLocked(r, filter, r.ordered); if (r.receiver == null || !r.ordered) { // The receiver has already finished, so schedule to // process the next one. if (DEBUG_BROADCAST) Slog.v( TAG, "Quick finishing [" + mQueueName + "]: ordered=" + r.ordered + " receiver=" + r.receiver); r.state = BroadcastRecord.IDLE; scheduleBroadcastsLocked(); } return; } // Hard case: need to instantiate the receiver, possibly // starting its application process to host it. ResolveInfo info = (ResolveInfo) nextReceiver; ComponentName component = new ComponentName(info.activityInfo.applicationInfo.packageName, info.activityInfo.name); boolean skip = false; int perm = mService.checkComponentPermission( info.activityInfo.permission, r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid, info.activityInfo.exported); if (perm != PackageManager.PERMISSION_GRANTED) { if (!info.activityInfo.exported) { Slog.w( TAG, "Permission Denial: broadcasting " + r.intent.toString() + " from " + r.callerPackage + " (pid=" + r.callingPid + ", uid=" + r.callingUid + ")" + " is not exported from uid " + info.activityInfo.applicationInfo.uid + " due to receiver " + component.flattenToShortString()); } else { Slog.w( TAG, "Permission Denial: broadcasting " + r.intent.toString() + " from " + r.callerPackage + " (pid=" + r.callingPid + ", uid=" + r.callingUid + ")" + " requires " + info.activityInfo.permission + " due to receiver " + component.flattenToShortString()); } skip = true; } if (info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID && r.requiredPermission != null) { try { perm = AppGlobals.getPackageManager() .checkPermission( r.requiredPermission, info.activityInfo.applicationInfo.packageName); } catch (RemoteException e) { perm = PackageManager.PERMISSION_DENIED; } if (perm != PackageManager.PERMISSION_GRANTED) { Slog.w( TAG, "Permission Denial: receiving " + r.intent + " to " + component.flattenToShortString() + " requires " + r.requiredPermission + " due to sender " + r.callerPackage + " (uid " + r.callingUid + ")"); skip = true; } } if (r.appOp != AppOpsManager.OP_NONE) { int mode = mService.mAppOpsService.checkOperation( r.appOp, info.activityInfo.applicationInfo.uid, info.activityInfo.packageName); if (mode != AppOpsManager.MODE_ALLOWED) { if (DEBUG_BROADCAST) Slog.v( TAG, "App op " + r.appOp + " not allowed for broadcast to uid " + info.activityInfo.applicationInfo.uid + " pkg " + info.activityInfo.packageName); skip = true; } } // MUTT if (mMuttFilter.hasAction(r.intent.getAction())) { Slog.v(TAG, "MUTT: whitelist broadcast " + r.intent.toString()); } else { if (mService.mBatteryStatsService.allowMutt( info.activityInfo.applicationInfo.uid, info.activityInfo.packageName) != 0) { Slog.w( TAG, "MUTT: skipping broadcasting " + r.intent.toString() + " from " + r.callerPackage + " (pid=" + r.callingPid + ", uid=" + r.callingUid + " to " + component.flattenToShortString() + ")"); skip = true; } } boolean isSingleton = false; try { isSingleton = mService.isSingleton( info.activityInfo.processName, info.activityInfo.applicationInfo, info.activityInfo.name, info.activityInfo.flags); } catch (SecurityException e) { Slog.w(TAG, e.getMessage()); skip = true; } if ((info.activityInfo.flags & ActivityInfo.FLAG_SINGLE_USER) != 0) { if (ActivityManager.checkUidPermission( android.Manifest.permission.INTERACT_ACROSS_USERS, info.activityInfo.applicationInfo.uid) != PackageManager.PERMISSION_GRANTED) { Slog.w( TAG, "Permission Denial: Receiver " + component.flattenToShortString() + " requests FLAG_SINGLE_USER, but app does not hold " + android.Manifest.permission.INTERACT_ACROSS_USERS); skip = true; } } if (r.curApp != null && r.curApp.crashing) { // If the target process is crashing, just skip it. if (DEBUG_BROADCAST) Slog.v( TAG, "Skipping deliver ordered [" + mQueueName + "] " + r + " to " + r.curApp + ": process crashing"); skip = true; } if (skip) { if (DEBUG_BROADCAST) Slog.v( TAG, "Skipping delivery of ordered [" + mQueueName + "] " + r + " for whatever reason"); r.receiver = null; r.curFilter = null; r.state = BroadcastRecord.IDLE; scheduleBroadcastsLocked(); return; } r.state = BroadcastRecord.APP_RECEIVE; String targetProcess = info.activityInfo.processName; r.curComponent = component; if (r.callingUid != Process.SYSTEM_UID && isSingleton) { info.activityInfo = mService.getActivityInfoForUser(info.activityInfo, 0); } r.curReceiver = info.activityInfo; if (DEBUG_MU && r.callingUid > UserHandle.PER_USER_RANGE) { Slog.v( TAG_MU, "Updated broadcast record activity info for secondary user, " + info.activityInfo + ", callingUid = " + r.callingUid + ", uid = " + info.activityInfo.applicationInfo.uid); } // Broadcast is being executed, its package can't be stopped. try { AppGlobals.getPackageManager() .setPackageStoppedState( r.curComponent.getPackageName(), false, UserHandle.getUserId(r.callingUid)); } catch (RemoteException e) { } catch (IllegalArgumentException e) { Slog.w( TAG, "Failed trying to unstop package " + r.curComponent.getPackageName() + ": " + e); } // Is this receiver's application already running? ProcessRecord app = mService.getProcessRecordLocked(targetProcess, info.activityInfo.applicationInfo.uid); if (app != null && app.thread != null) { try { app.addPackage(info.activityInfo.packageName); processCurBroadcastLocked(r, app); return; } catch (RemoteException e) { Slog.w(TAG, "Exception when sending broadcast to " + r.curComponent, e); } catch (RuntimeException e) { Log.wtf(TAG, "Failed sending broadcast to " + r.curComponent + " with " + r.intent, e); // If some unexpected exception happened, just skip // this broadcast. At this point we are not in the call // from a client, so throwing an exception out from here // will crash the entire system instead of just whoever // sent the broadcast. logBroadcastReceiverDiscardLocked(r); finishReceiverLocked(r, r.resultCode, r.resultData, r.resultExtras, r.resultAbort, true); scheduleBroadcastsLocked(); // We need to reset the state if we failed to start the receiver. r.state = BroadcastRecord.IDLE; return; } // If a dead object exception was thrown -- fall through to // restart the application. } // Not running -- get it started, to be executed when the app comes up. if (DEBUG_BROADCAST) Slog.v( TAG, "Need to start app [" + mQueueName + "] " + targetProcess + " for broadcast " + r); if ((r.curApp = mService.startProcessLocked( targetProcess, info.activityInfo.applicationInfo, true, r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND, "broadcast", r.curComponent, (r.intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0, false)) == null) { // Ah, this recipient is unavailable. Finish it if necessary, // and mark the broadcast record as ready for the next. Slog.w( TAG, "Unable to launch app " + info.activityInfo.applicationInfo.packageName + "/" + info.activityInfo.applicationInfo.uid + " for broadcast " + r.intent + ": process is bad"); logBroadcastReceiverDiscardLocked(r); finishReceiverLocked(r, r.resultCode, r.resultData, r.resultExtras, r.resultAbort, true); scheduleBroadcastsLocked(); r.state = BroadcastRecord.IDLE; return; } mPendingBroadcast = r; mPendingBroadcastRecvIndex = recIdx; } }
public int getUserId() { return UserHandle.getUserId(callingUid); }
private JobStatus( JobInfo job, int callingUid, String sourcePackageName, int sourceUserId, String tag, int numFailures, long earliestRunTimeElapsedMillis, long latestRunTimeElapsedMillis) { this.job = job; this.callingUid = callingUid; int tempSourceUid = -1; if (sourceUserId != -1 && sourcePackageName != null) { try { tempSourceUid = AppGlobals.getPackageManager().getPackageUid(sourcePackageName, 0, sourceUserId); } catch (RemoteException ex) { // Can't happen, PackageManager runs in the same process. } } if (tempSourceUid == -1) { this.sourceUid = callingUid; this.sourceUserId = UserHandle.getUserId(callingUid); this.sourcePackageName = job.getService().getPackageName(); this.sourceTag = null; } else { this.sourceUid = tempSourceUid; this.sourceUserId = sourceUserId; this.sourcePackageName = sourcePackageName; this.sourceTag = tag; } this.batteryName = this.sourceTag != null ? this.sourceTag + ":" + job.getService().getPackageName() : job.getService().flattenToShortString(); this.tag = "*job*/" + this.batteryName; this.earliestRunTimeElapsedMillis = earliestRunTimeElapsedMillis; this.latestRunTimeElapsedMillis = latestRunTimeElapsedMillis; this.numFailures = numFailures; int requiredConstraints = 0; if (job.getNetworkType() == JobInfo.NETWORK_TYPE_ANY) { requiredConstraints |= CONSTRAINT_CONNECTIVITY; } if (job.getNetworkType() == JobInfo.NETWORK_TYPE_UNMETERED) { requiredConstraints |= CONSTRAINT_UNMETERED; } if (job.getNetworkType() == JobInfo.NETWORK_TYPE_NOT_ROAMING) { requiredConstraints |= CONSTRAINT_NOT_ROAMING; } if (job.isRequireCharging()) { requiredConstraints |= CONSTRAINT_CHARGING; } if (earliestRunTimeElapsedMillis != NO_EARLIEST_RUNTIME) { requiredConstraints |= CONSTRAINT_TIMING_DELAY; } if (latestRunTimeElapsedMillis != NO_LATEST_RUNTIME) { requiredConstraints |= CONSTRAINT_DEADLINE; } if (job.isRequireDeviceIdle()) { requiredConstraints |= CONSTRAINT_IDLE; } if (job.getTriggerContentUris() != null) { requiredConstraints |= CONSTRAINT_CONTENT_TRIGGER; } this.requiredConstraints = requiredConstraints; }
public ProcessItem(Context context, int uid, String processName) { super(true, UserHandle.getUserId(uid)); mDescription = context.getResources().getString(R.string.service_process_name, processName); mUid = uid; mProcessName = processName; }