代码位于frameworks/base/services/core/java/com/android/server/am/,一共有七十个文件。
Java源码位于package com.android.server.am里
下面是消息处理部分
处理应用崩溃消息
1 14223 /** 2 14224 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 3 14225 * The application process will exit immediately after this call returns. 4 14226 * @param app object of the crashing app, null for the system server 5 14227 * @param crashInfo describing the exception 6 14228 */ 7 14229 public void handleApplicationCrash(IBinder app, 8 14230 ApplicationErrorReport.ParcelableCrashInfo crashInfo) { 9 14231 ProcessRecord r = findAppProcess(app, "Crash"); 10 14232 final String processName = app == null ? "system_server" 11 14233 : (r == null ? "unknown" : r.processName); 12 14234 13 14235 handleApplicationCrashInner("crash", r, processName, crashInfo); 14 14236 } 15 14237 16 14238 /* Native crash reporting uses this inner version because it needs to be somewhat 17 14239 * decoupled from the AM-managed cleanup lifecycle 18 14240 */ 19 14241 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 20 14242 ApplicationErrorReport.CrashInfo crashInfo) { 21 14243 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 22 14244 UserHandle.getUserId(Binder.getCallingUid()), processName, 23 14245 r == null ? -1 : r.info.flags, 24 14246 crashInfo.exceptionClassName, 25 14247 crashInfo.exceptionMessage, 26 14248 crashInfo.throwFileName, 27 14249 crashInfo.throwLineNumber); 28 14250 29 14251 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 30 14252 31 14253 mAppErrors.crashApplication(r, crashInfo); 32 14254 }
处理应用违反strict mode策略
1 14256 public void handleApplicationStrictModeViolation( 2 14257 IBinder app, 3 14258 int violationMask, 4 14259 StrictMode.ViolationInfo info) { 5 14260 ProcessRecord r = findAppProcess(app, "StrictMode"); 6 14261 if (r == null) { 7 14262 return; 8 14263 } 9 14264 10 14265 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11 14266 Integer stackFingerprint = info.hashCode(); 12 14267 boolean logIt = true; 13 14268 synchronized (mAlreadyLoggedViolatedStacks) { 14 14269 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 15 14270 logIt = false; 16 14271 // TODO: sub-sample into EventLog for these, with 17 14272 // the info.durationMillis? Then we'd get 18 14273 // the relative pain numbers, without logging all 19 14274 // the stack traces repeatedly. We'd want to do 20 14275 // likewise in the client code, which also does 21 14276 // dup suppression, before the Binder call. 22 14277 } else { 23 14278 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 24 14279 mAlreadyLoggedViolatedStacks.clear(); 25 14280 } 26 14281 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 27 14282 } 28 14283 } 29 14284 if (logIt) { 30 14285 logStrictModeViolationToDropBox(r, info); 31 14286 } 32 14287 } 33 14288 34 14289 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 35 14290 AppErrorResult result = new AppErrorResult(); 36 14291 synchronized (this) { 37 14292 final long origId = Binder.clearCallingIdentity(); 38 14293 39 14294 Message msg = Message.obtain(); 40 14295 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG; 41 14296 HashMap<String, Object> data = new HashMap<String, Object>(); 42 14297 data.put("result", result); 43 14298 data.put("app", r); 44 14299 data.put("violationMask", violationMask); 45 14300 data.put("info", info); 46 14301 msg.obj = data; 47 14302 mUiHandler.sendMessage(msg); 48 14303 49 14304 Binder.restoreCallingIdentity(origId); 50 14305 } 51 14306 int res = result.get(); 52 14307 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 53 14308 } 54 14309 }
记录违反strict mode的行为放到dropbox
1 14311 // Depending on the policy in effect, there could be a bunch of 2 14312 // these in quick succession so we try to batch these together to 3 14313 // minimize disk writes, number of dropbox entries, and maximize 4 14314 // compression, by having more fewer, larger records. 5 14315 private void logStrictModeViolationToDropBox( 6 14316 ProcessRecord process, 7 14317 StrictMode.ViolationInfo info) { 8 14318 if (info == null) { 9 14319 return; 10 14320 } 11 14321 final boolean isSystemApp = process == null || 12 14322 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 13 14323 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 14 14324 final String processName = process == null ? "unknown" : process.processName; 15 14325 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 16 14326 final DropBoxManager dbox = (DropBoxManager) 17 14327 mContext.getSystemService(Context.DROPBOX_SERVICE); 18 14328 19 14329 // Exit early if the dropbox isn't configured to accept this report type. 20 14330 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 21 14331 22 14332 boolean bufferWasEmpty; 23 14333 boolean needsFlush; 24 14334 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 25 14335 synchronized (sb) { 26 14336 bufferWasEmpty = sb.length() == 0; 27 14337 appendDropBoxProcessHeaders(process, processName, sb); 28 14338 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 29 14339 sb.append("System-App: ").append(isSystemApp).append("\n"); 30 14340 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 31 14341 if (info.violationNumThisLoop != 0) { 32 14342 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 33 14343 } 34 14344 if (info.numAnimationsRunning != 0) { 35 14345 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 36 14346 } 37 14347 if (info.broadcastIntentAction != null) { 38 14348 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 39 14349 } 40 14350 if (info.durationMillis != -1) { 41 14351 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 42 14352 } 43 14353 if (info.numInstances != -1) { 44 14354 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 45 14355 } 46 14356 if (info.tags != null) { 47 14357 for (String tag : info.tags) { 48 14358 sb.append("Span-Tag: ").append(tag).append("\n"); 49 14359 } 50 14360 } 51 14361 sb.append("\n"); 52 14362 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 53 14363 sb.append(info.crashInfo.stackTrace); 54 14364 sb.append("\n"); 55 14365 } 56 14366 if (info.message != null) { 57 14367 sb.append(info.message); 58 14368 sb.append("\n"); 59 14369 } 60 14370 61 14371 // Only buffer up to ~64k. Various logging bits truncate 62 14372 // things at 128k. 63 14373 needsFlush = (sb.length() > 64 * 1024); 64 14374 } 65 14375 66 14376 // Flush immediately if the buffer's grown too large, or this 67 14377 // is a non-system app. Non-system apps are isolated with a 68 14378 // different tag & policy and not batched. 69 14379 // 70 14380 // Batching is useful during internal testing with 71 14381 // StrictMode settings turned up high. Without batching, 72 14382 // thousands of separate files could be created on boot. 73 14383 if (!isSystemApp || needsFlush) { 74 14384 new Thread("Error dump: " + dropboxTag) { 75 14385 @Override 76 14386 public void run() { 77 14387 String report; 78 14388 synchronized (sb) { 79 14389 report = sb.toString(); 80 14390 sb.delete(0, sb.length()); 81 14391 sb.trimToSize(); 82 14392 } 83 14393 if (report.length() != 0) { 84 14394 dbox.addText(dropboxTag, report); 85 14395 } 86 14396 } 87 14397 }.start(); 88 14398 return; 89 14399 } 90 14400 91 14401 // System app batching: 92 14402 if (!bufferWasEmpty) { 93 14403 // An existing dropbox-writing thread is outstanding, so 94 14404 // we don't need to start it up. The existing thread will 95 14405 // catch the buffer appends we just did. 96 14406 return; 97 14407 } 98 14408 99 14409 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 100 14410 // (After this point, we shouldn't access AMS internal data structures.) 101 14411 new Thread("Error dump: " + dropboxTag) { 102 14412 @Override 103 14413 public void run() { 104 14414 // 5 second sleep to let stacks arrive and be batched together 105 14415 try { 106 14416 Thread.sleep(5000); // 5 seconds 107 14417 } catch (InterruptedException e) {} 108 14418 109 14419 String errorReport; 110 14420 synchronized (mStrictModeBuffer) { 111 14421 errorReport = mStrictModeBuffer.toString(); 112 14422 if (errorReport.length() == 0) { 113 14423 return; 114 14424 } 115 14425 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 116 14426 mStrictModeBuffer.trimToSize(); 117 14427 } 118 14428 dbox.addText(dropboxTag, errorReport); 119 14429 } 120 14430 }.start(); 121 14431 }
处理应用wtf
1 14433 /** 2 14434 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 3 14435 * @param app object of the crashing app, null for the system server 4 14436 * @param tag reported by the caller 5 14437 * @param system whether this wtf is coming from the system 6 14438 * @param crashInfo describing the context of the error 7 14439 * @return true if the process should exit immediately (WTF is fatal) 8 14440 */ 9 14441 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system, 10 14442 final ApplicationErrorReport.ParcelableCrashInfo crashInfo) { 11 14443 final int callingUid = Binder.getCallingUid(); 12 14444 final int callingPid = Binder.getCallingPid(); 13 14445 14 14446 if (system) { 15 14447 // If this is coming from the system, we could very well have low-level 16 14448 // system locks held, so we want to do this all asynchronously. And we 17 14449 // never want this to become fatal, so there is that too. 18 14450 mHandler.post(new Runnable() { 19 14451 @Override public void run() { 20 14452 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo); 21 14453 } 22 14454 }); 23 14455 return false; 24 14456 } 25 14457 26 14458 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag, 27 14459 crashInfo); 28 14460 29 14461 final boolean isFatal = "eng".equals(Build.TYPE) || Settings.Global 30 14462 .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0; 31 14463 final boolean isSystem = (r == null) || r.persistent; 32 14464 33 14465 if (isFatal && !isSystem) { 34 14466 mAppErrors.crashApplication(r, crashInfo); 35 14467 return true; 36 14468 } else { 37 14469 return false; 38 14470 } 39 14471 } 40 14472 41 14473 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag, 42 14474 final ApplicationErrorReport.CrashInfo crashInfo) { 43 14475 final ProcessRecord r = findAppProcess(app, "WTF"); 44 14476 final String processName = app == null ? "system_server" 45 14477 : (r == null ? "unknown" : r.processName); 46 14478 47 14479 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid, 48 14480 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage); 49 14481 50 14482 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 51 14483 52 14484 return r; 53 14485 }
找到应用的process
1 14486 2 14487 /** 3 14488 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 4 14489 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 5 14490 */ 6 14491 private ProcessRecord findAppProcess(IBinder app, String reason) { 7 14492 if (app == null) { 8 14493 return null; 9 14494 } 10 14495 11 14496 synchronized (this) { 12 14497 final int NP = mProcessNames.getMap().size(); 13 14498 for (int ip=0; ip<NP; ip++) { 14 14499 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 15 14500 final int NA = apps.size(); 16 14501 for (int ia=0; ia<NA; ia++) { 17 14502 ProcessRecord p = apps.valueAt(ia); 18 14503 if (p.thread != null && p.thread.asBinder() == app) { 19 14504 return p; 20 14505 } 21 14506 } 22 14507 } 23 14508 24 14509 Slog.w(TAG, "Can't find mystery application for " + reason 25 14510 + " from pid=" + Binder.getCallingPid() 26 14511 + " uid=" + Binder.getCallingUid() + ": " + app); 27 14512 return null; 28 14513 } 29 14514 }
添加dropbox里进程头
1 14516 /** 2 14517 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 3 14518 * to append various headers to the dropbox log text. 4 14519 */ 5 14520 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 6 14521 StringBuilder sb) { 7 14522 // Watchdog thread ends up invoking this function (with 8 14523 // a null ProcessRecord) to add the stack file to dropbox. 9 14524 // Do not acquire a lock on this (am) in such cases, as it 10 14525 // could cause a potential deadlock, if and when watchdog 11 14526 // is invoked due to unavailability of lock on am and it 12 14527 // would prevent watchdog from killing system_server. 13 14528 if (process == null) { 14 14529 sb.append("Process: ").append(processName).append("\n"); 15 14530 return; 16 14531 } 17 14532 // Note: ProcessRecord 'process' is guarded by the service 18 14533 // instance. (notably process.pkgList, which could otherwise change 19 14534 // concurrently during execution of this method) 20 14535 synchronized (this) { 21 14536 sb.append("Process: ").append(processName).append("\n"); 22 14537 sb.append("PID: ").append(process.pid).append("\n"); 23 14538 int flags = process.info.flags; 24 14539 IPackageManager pm = AppGlobals.getPackageManager(); 25 14540 sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n"); 26 14541 for (int ip=0; ip<process.pkgList.size(); ip++) { 27 14542 String pkg = process.pkgList.keyAt(ip); 28 14543 sb.append("Package: ").append(pkg); 29 14544 try { 30 14545 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 31 14546 if (pi != null) { 32 14547 sb.append(" v").append(pi.versionCode); 33 14548 if (pi.versionName != null) { 34 14549 sb.append(" (").append(pi.versionName).append(")"); 35 14550 } 36 14551 } 37 14552 } catch (RemoteException e) { 38 14553 Slog.e(TAG, "Error getting package info: " + pkg, e); 39 14554 } 40 14555 sb.append("\n"); 41 14556 } 42 14557 } 43 14558 }
进程的类别
1 14560 private static String processClass(ProcessRecord process) { 2 14561 if (process == null || process.pid == MY_PID) { 3 14562 return "system_server"; 4 14563 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 5 14564 return "system_app"; 6 14565 } else { 7 14566 return "data_app"; 8 14567 } 9 14568 }
wtf的start和count
1 14570 private volatile long mWtfClusterStart; 2 14571 private volatile int mWtfClusterCount;
添加错误到dropbox
1 14573 /** 2 14574 * Write a description of an error (crash, WTF, ANR) to the drop box. 3 14575 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 4 14576 * @param process which caused the error, null means the system server 5 14577 * @param activity which triggered the error, null if unknown 6 14578 * @param parent activity related to the error, null if unknown 7 14579 * @param subject line related to the error, null if absent 8 14580 * @param report in long form describing the error, null if absent 9 14581 * @param dataFile text file to include in the report, null if none 10 14582 * @param crashInfo giving an application stack trace, null if absent 11 14583 */ 12 14584 public void addErrorToDropBox(String eventType, 13 14585 ProcessRecord process, String processName, ActivityRecord activity, 14 14586 ActivityRecord parent, String subject, 15 14587 final String report, final File dataFile, 16 14588 final ApplicationErrorReport.CrashInfo crashInfo) { 17 14589 // NOTE -- this must never acquire the ActivityManagerService lock, 18 14590 // otherwise the watchdog may be prevented from resetting the system. 19 14591 20 14592 // Bail early if not published yet 21 14593 if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return; 22 14594 final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class); 23 14595 24 14596 // Exit early if the dropbox isn't configured to accept this report type. 25 14597 final String dropboxTag = processClass(process) + "_" + eventType; 26 14598 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 27 14599 28 14600 // Rate-limit how often we're willing to do the heavy lifting below to 29 14601 // collect and record logs; currently 5 logs per 10 second period. 30 14602 final long now = SystemClock.elapsedRealtime(); 31 14603 if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) { 32 14604 mWtfClusterStart = now; 33 14605 mWtfClusterCount = 1; 34 14606 } else { 35 14607 if (mWtfClusterCount++ >= 5) return; 36 14608 } 37 14609 38 14610 final StringBuilder sb = new StringBuilder(1024); 39 14611 appendDropBoxProcessHeaders(process, processName, sb); 40 14612 if (process != null) { 41 14613 sb.append("Foreground: ") 42 14614 .append(process.isInterestingToUserLocked() ? "Yes" : "No") 43 14615 .append("\n"); 44 14616 } 45 14617 if (activity != null) { 46 14618 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 47 14619 } 48 14620 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 49 14621 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 50 14622 } 51 14623 if (parent != null && parent != activity) { 52 14624 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 53 14625 } 54 14626 if (subject != null) { 55 14627 sb.append("Subject: ").append(subject).append("\n"); 56 14628 } 57 14629 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 58 14630 if (Debug.isDebuggerConnected()) { 59 14631 sb.append("Debugger: Connected\n"); 60 14632 } 61 14633 sb.append("\n"); 62 14634 63 14635 // Do the rest in a worker thread to avoid blocking the caller on I/O 64 14636 // (After this point, we shouldn't access AMS internal data structures.) 65 14637 Thread worker = new Thread("Error dump: " + dropboxTag) { 66 14638 @Override 67 14639 public void run() { 68 14640 if (report != null) { 69 14641 sb.append(report); 70 14642 } 71 14643 72 14644 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 73 14645 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 74 14646 int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length() 75 14647 - lines * RESERVED_BYTES_PER_LOGCAT_LINE; 76 14648 77 14649 if (dataFile != null && maxDataFileSize > 0) { 78 14650 try { 79 14651 sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize, 80 14652 "\n\n[[TRUNCATED]]")); 81 14653 } catch (IOException e) { 82 14654 Slog.e(TAG, "Error reading " + dataFile, e); 83 14655 } 84 14656 } 85 14657 if (crashInfo != null && crashInfo.stackTrace != null) { 86 14658 sb.append(crashInfo.stackTrace); 87 14659 } 88 14660 89 14661 if (lines > 0) { 90 14662 sb.append("\n"); 91 14663 92 14664 // Merge several logcat streams, and take the last N lines 93 14665 InputStreamReader input = null; 94 14666 try { 95 14667 java.lang.Process logcat = new ProcessBuilder( 96 14668 "/system/bin/timeout", "-k", "15s", "10s", 97 14669 "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system", 98 14670 "-b", "main", "-b", "crash", "-t", String.valueOf(lines)) 99 14671 .redirectErrorStream(true).start(); 100 14672 101 14673 try { logcat.getOutputStream().close(); } catch (IOException e) {} 102 14674 try { logcat.getErrorStream().close(); } catch (IOException e) {} 103 14675 input = new InputStreamReader(logcat.getInputStream()); 104 14676 105 14677 int num; 106 14678 char[] buf = new char[8192]; 107 14679 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 108 14680 } catch (IOException e) { 109 14681 Slog.e(TAG, "Error running logcat", e); 110 14682 } finally { 111 14683 if (input != null) try { input.close(); } catch (IOException e) {} 112 14684 } 113 14685 } 114 14686 115 14687 dbox.addText(dropboxTag, sb.toString()); 116 14688 } 117 14689 }; 118 14690 119 14691 if (process == null) { 120 14692 // If process is null, we are being called from some internal code 121 14693 // and may be about to die -- run this synchronously. 122 14694 worker.run(); 123 14695 } else { 124 14696 worker.start(); 125 14697 } 126 14698 }
在错误状态下获取进程信息
1 14700 @Override 2 14701 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 3 14702 enforceNotIsolatedCaller("getProcessesInErrorState"); 4 14703 // assume our apps are happy - lazy create the list 5 14704 List<ActivityManager.ProcessErrorStateInfo> errList = null; 6 14705 7 14706 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 8 14707 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 9 14708 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10 14709 11 14710 synchronized (this) { 12 14711 13 14712 // iterate across all processes 14 14713 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15 14714 ProcessRecord app = mLruProcesses.get(i); 16 14715 if (!allUsers && app.userId != userId) { 17 14716 continue; 18 14717 } 19 14718 if ((app.thread != null) && (app.crashing || app.notResponding)) { 20 14719 // This one's in trouble, so we'll generate a report for it 21 14720 // crashes are higher priority (in case there's a crash *and* an anr) 22 14721 ActivityManager.ProcessErrorStateInfo report = null; 23 14722 if (app.crashing) { 24 14723 report = app.crashingReport; 25 14724 } else if (app.notResponding) { 26 14725 report = app.notRespondingReport; 27 14726 } 28 14727 29 14728 if (report != null) { 30 14729 if (errList == null) { 31 14730 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 32 14731 } 33 14732 errList.add(report); 34 14733 } else { 35 14734 Slog.w(TAG, "Missing app error report, app = " + app.processName + 36 14735 " crashing = " + app.crashing + 37 14736 " notResponding = " + app.notResponding); 38 14737 } 39 14738 } 40 14739 } 41 14740 } 42 14741 43 14742 return errList; 44 14743 }
进程状态的重要值
1 14745 static int procStateToImportance(int procState, int memAdj, 2 14746 ActivityManager.RunningAppProcessInfo currApp, 3 14747 int clientTargetSdk) { 4 14748 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk( 5 14749 procState, clientTargetSdk); 6 14750 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 7 14751 currApp.lru = memAdj; 8 14752 } else { 9 14753 currApp.lru = 0; 10 14754 } 11 14755 return imp; 12 14756 }
填写进程内存info
1 14758 private void fillInProcMemInfo(ProcessRecord app, 2 14759 ActivityManager.RunningAppProcessInfo outInfo, 3 14760 int clientTargetSdk) { 4 14761 outInfo.pid = app.pid; 5 14762 outInfo.uid = app.info.uid; 6 14763 if (mHeavyWeightProcess == app) { 7 14764 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 8 14765 } 9 14766 if (app.persistent) { 10 14767 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 11 14768 } 12 14769 if (app.activities.size() > 0) { 13 14770 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 14 14771 } 15 14772 outInfo.lastTrimLevel = app.trimMemoryLevel; 16 14773 int adj = app.curAdj; 17 14774 int procState = app.curProcState; 18 14775 outInfo.importance = procStateToImportance(procState, adj, outInfo, clientTargetSdk); 19 14776 outInfo.importanceReasonCode = app.adjTypeCode; 20 14777 outInfo.processState = app.curProcState; 21 14778 }
获取运行进程信息,运行外部程序,system_server的内存状态与trim内存状态
1 14780 @Override 2 14781 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 3 14782 enforceNotIsolatedCaller("getRunningAppProcesses"); 4 14783 5 14784 final int callingUid = Binder.getCallingUid(); 6 14785 final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid); 7 14786 8 14787 // Lazy instantiation of list 9 14788 List<ActivityManager.RunningAppProcessInfo> runList = null; 10 14789 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 11 14790 callingUid) == PackageManager.PERMISSION_GRANTED; 12 14791 final int userId = UserHandle.getUserId(callingUid); 13 14792 final boolean allUids = isGetTasksAllowed( 14 14793 "getRunningAppProcesses", Binder.getCallingPid(), callingUid); 15 14794 16 14795 synchronized (this) { 17 14796 // Iterate across all processes 18 14797 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 19 14798 ProcessRecord app = mLruProcesses.get(i); 20 14799 if ((!allUsers && app.userId != userId) 21 14800 || (!allUids && app.uid != callingUid)) { 22 14801 continue; 23 14802 } 24 14803 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 25 14804 // Generate process state info for running application 26 14805 ActivityManager.RunningAppProcessInfo currApp = 27 14806 new ActivityManager.RunningAppProcessInfo(app.processName, 28 14807 app.pid, app.getPackageList()); 29 14808 fillInProcMemInfo(app, currApp, clientTargetSdk); 30 14809 if (app.adjSource instanceof ProcessRecord) { 31 14810 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 32 14811 currApp.importanceReasonImportance = 33 14812 ActivityManager.RunningAppProcessInfo.procStateToImportance( 34 14813 app.adjSourceProcState); 35 14814 } else if (app.adjSource instanceof ActivityRecord) { 36 14815 ActivityRecord r = (ActivityRecord)app.adjSource; 37 14816 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 38 14817 } 39 14818 if (app.adjTarget instanceof ComponentName) { 40 14819 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 41 14820 } 42 14821 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 43 14822 // + " lru=" + currApp.lru); 44 14823 if (runList == null) { 45 14824 runList = new ArrayList<>(); 46 14825 } 47 14826 runList.add(currApp); 48 14827 } 49 14828 } 50 14829 } 51 14830 return runList; 52 14831 } 53 14832 54 14833 @Override 55 14834 public List<ApplicationInfo> getRunningExternalApplications() { 56 14835 enforceNotIsolatedCaller("getRunningExternalApplications"); 57 14836 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 58 14837 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 59 14838 if (runningApps != null && runningApps.size() > 0) { 60 14839 Set<String> extList = new HashSet<String>(); 61 14840 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 62 14841 if (app.pkgList != null) { 63 14842 for (String pkg : app.pkgList) { 64 14843 extList.add(pkg); 65 14844 } 66 14845 } 67 14846 } 68 14847 IPackageManager pm = AppGlobals.getPackageManager(); 69 14848 for (String pkg : extList) { 70 14849 try { 71 14850 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 72 14851 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 73 14852 retList.add(info); 74 14853 } 75 14854 } catch (RemoteException e) { 76 14855 } 77 14856 } 78 14857 } 79 14858 return retList; 80 14859 } 81 14860 82 14861 @Override 83 14862 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 84 14863 enforceNotIsolatedCaller("getMyMemoryState"); 85 14864 86 14865 final int callingUid = Binder.getCallingUid(); 87 14866 final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid); 88 14867 89 14868 synchronized (this) { 90 14869 ProcessRecord proc; 91 14870 synchronized (mPidsSelfLocked) { 92 14871 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 93 14872 } 94 14873 fillInProcMemInfo(proc, outInfo, clientTargetSdk); 95 14874 } 96 14875 } 97 14876 98 14877 @Override 99 14878 public int getMemoryTrimLevel() { 100 14879 enforceNotIsolatedCaller("getMyMemoryState"); 101 14880 synchronized (this) { 102 14881 return mLastMemoryLevel; 103 14882 } 104 14883 }
shell command回调
1 14885 @Override 2 14886 public void onShellCommand(FileDescriptor in, FileDescriptor out, 3 14887 FileDescriptor err, String[] args, ShellCallback callback, 4 14888 ResultReceiver resultReceiver) { 5 14889 (new ActivityManagerShellCommand(this, false)).exec( 6 14890 this, in, out, err, args, callback, resultReceiver); 7 14891 } 8 14892
dump
1 14893 @Override 2 14894 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 3 14895 if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return; 4 14896 5 14897 boolean dumpAll = false; 6 14898 boolean dumpClient = false; 7 14899 boolean dumpCheckin = false; 8 14900 boolean dumpCheckinFormat = false; 9 14901 boolean dumpVisibleStacksOnly = false; 10 14902 boolean dumpFocusedStackOnly = false; 11 14903 String dumpPackage = null; 12 14904 13 14905 int opti = 0; 14 14906 while (opti < args.length) { 15 14907 String opt = args[opti]; 16 14908 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 17 14909 break; 18 14910 } 19 14911 opti++; 20 14912 if ("-a".equals(opt)) { 21 14913 dumpAll = true; 22 14914 } else if ("-c".equals(opt)) { 23 14915 dumpClient = true; 24 14916 } else if ("-v".equals(opt)) { 25 14917 dumpVisibleStacksOnly = true; 26 14918 } else if ("-f".equals(opt)) { 27 14919 dumpFocusedStackOnly = true; 28 14920 } else if ("-p".equals(opt)) { 29 14921 if (opti < args.length) { 30 14922 dumpPackage = args[opti]; 31 14923 opti++; 32 14924 } else { 33 14925 pw.println("Error: -p option requires package argument"); 34 14926 return; 35 14927 } 36 14928 dumpClient = true; 37 14929 } else if ("--checkin".equals(opt)) { 38 14930 dumpCheckin = dumpCheckinFormat = true; 39 14931 } else if ("-C".equals(opt)) { 40 14932 dumpCheckinFormat = true; 41 14933 } else if ("-h".equals(opt)) { 42 14934 ActivityManagerShellCommand.dumpHelp(pw, true); 43 14935 return; 44 14936 } else { 45 14937 pw.println("Unknown argument: " + opt + "; use -h for help"); 46 14938 } 47 14939 } 48 14940 49 14941 long origId = Binder.clearCallingIdentity(); 50 14942 boolean more = false; 51 14943 // Is the caller requesting to dump a particular piece of data? 52 14944 if (opti < args.length) { 53 14945 String cmd = args[opti]; 54 14946 opti++; 55 14947 if ("activities".equals(cmd) || "a".equals(cmd)) { 56 14948 synchronized (this) { 57 14949 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage); 58 14950 } 59 14951 } else if ("lastanr".equals(cmd)) { 60 14952 synchronized (this) { 61 14953 dumpLastANRLocked(pw); 62 14954 } 63 14955 } else if ("starter".equals(cmd)) { 64 14956 synchronized (this) { 65 14957 dumpActivityStarterLocked(pw); 66 14958 } 67 14959 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 68 14960 synchronized (this) { 69 14961 dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage); 70 14962 } 71 14963 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 72 14964 String[] newArgs; 73 14965 String name; 74 14966 if (opti >= args.length) { 75 14967 name = null; 76 14968 newArgs = EMPTY_STRING_ARRAY; 77 14969 } else { 78 14970 dumpPackage = args[opti]; 79 14971 opti++; 80 14972 newArgs = new String[args.length - opti]; 81 14973 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 82 14974 args.length - opti); 83 14975 } 84 14976 synchronized (this) { 85 14977 dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage); 86 14978 } 87 14979 } else if ("broadcast-stats".equals(cmd)) { 88 14980 String[] newArgs; 89 14981 String name; 90 14982 if (opti >= args.length) { 91 14983 name = null; 92 14984 newArgs = EMPTY_STRING_ARRAY; 93 14985 } else { 94 14986 dumpPackage = args[opti]; 95 14987 opti++; 96 14988 newArgs = new String[args.length - opti]; 97 14989 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 98 14990 args.length - opti); 99 14991 } 100 14992 synchronized (this) { 101 14993 if (dumpCheckinFormat) { 102 14994 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, 103 14995 dumpPackage); 104 14996 } else { 105 14997 dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage); 106 14998 } 107 14999 } 108 15000 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 109 15001 String[] newArgs; 110 15002 String name; 111 15003 if (opti >= args.length) { 112 15004 name = null; 113 15005 newArgs = EMPTY_STRING_ARRAY; 114 15006 } else { 115 15007 dumpPackage = args[opti]; 116 15008 opti++; 117 15009 newArgs = new String[args.length - opti]; 118 15010 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 119 15011 args.length - opti); 120 15012 } 121 15013 synchronized (this) { 122 15014 dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage); 123 15015 } 124 15016 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 125 15017 String[] newArgs; 126 15018 String name; 127 15019 if (opti >= args.length) { 128 15020 name = null; 129 15021 newArgs = EMPTY_STRING_ARRAY; 130 15022 } else { 131 15023 dumpPackage = args[opti]; 132 15024 opti++; 133 15025 newArgs = new String[args.length - opti]; 134 15026 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 135 15027 args.length - opti); 136 15028 } 137 15029 synchronized (this) { 138 15030 dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage); 139 15031 } 140 15032 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 141 15033 synchronized (this) { 142 15034 dumpOomLocked(fd, pw, args, opti, true); 143 15035 } 144 15036 } else if ("permissions".equals(cmd) || "perm".equals(cmd)) { 145 15037 synchronized (this) { 146 15038 dumpPermissionsLocked(fd, pw, args, opti, true, null); 147 15039 } 148 15040 } else if ("provider".equals(cmd)) { 149 15041 String[] newArgs; 150 15042 String name; 151 15043 if (opti >= args.length) { 152 15044 name = null; 153 15045 newArgs = EMPTY_STRING_ARRAY; 154 15046 } else { 155 15047 name = args[opti]; 156 15048 opti++; 157 15049 newArgs = new String[args.length - opti]; 158 15050 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 159 15051 } 160 15052 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 161 15053 pw.println("No providers match: " + name); 162 15054 pw.println("Use -h for help."); 163 15055 } 164 15056 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 165 15057 synchronized (this) { 166 15058 dumpProvidersLocked(fd, pw, args, opti, true, null); 167 15059 } 168 15060 } else if ("service".equals(cmd)) { 169 15061 String[] newArgs; 170 15062 String name; 171 15063 if (opti >= args.length) { 172 15064 name = null; 173 15065 newArgs = EMPTY_STRING_ARRAY; 174 15066 } else { 175 15067 name = args[opti]; 176 15068 opti++; 177 15069 newArgs = new String[args.length - opti]; 178 15070 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 179 15071 args.length - opti); 180 15072 } 181 15073 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 182 15074 pw.println("No services match: " + name); 183 15075 pw.println("Use -h for help."); 184 15076 } 185 15077 } else if ("package".equals(cmd)) { 186 15078 String[] newArgs; 187 15079 if (opti >= args.length) { 188 15080 pw.println("package: no package name specified"); 189 15081 pw.println("Use -h for help."); 190 15082 } else { 191 15083 dumpPackage = args[opti]; 192 15084 opti++; 193 15085 newArgs = new String[args.length - opti]; 194 15086 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 195 15087 args.length - opti); 196 15088 args = newArgs; 197 15089 opti = 0; 198 15090 more = true; 199 15091 } 200 15092 } else if ("associations".equals(cmd) || "as".equals(cmd)) { 201 15093 synchronized (this) { 202 15094 dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage); 203 15095 } 204 15096 } else if ("settings".equals(cmd)) { 205 15097 synchronized (this) { 206 15098 mConstants.dump(pw); 207 15099 } 208 15100 } else if ("services".equals(cmd) || "s".equals(cmd)) { 209 15101 if (dumpClient) { 210 15102 ActiveServices.ServiceDumper dumper; 211 15103 synchronized (this) { 212 15104 dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true, 213 15105 dumpPackage); 214 15106 } 215 15107 dumper.dumpWithClient(); 216 15108 } else { 217 15109 synchronized (this) { 218 15110 mServices.newServiceDumperLocked(fd, pw, args, opti, true, 219 15111 dumpPackage).dumpLocked(); 220 15112 } 221 15113 } 222 15114 } else if ("locks".equals(cmd)) { 223 15115 LockGuard.dump(fd, pw, args); 224 15116 } else { 225 15117 // Dumping a single activity? 226 15118 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly, 227 15119 dumpFocusedStackOnly)) { 228 15120 ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true); 229 15121 int res = shell.exec(this, null, fd, null, args, null, 230 15122 new ResultReceiver(null)); 231 15123 if (res < 0) { 232 15124 pw.println("Bad activity command, or no activities match: " + cmd); 233 15125 pw.println("Use -h for help."); 234 15126 } 235 15127 } 236 15128 } 237 15129 if (!more) { 238 15130 Binder.restoreCallingIdentity(origId); 239 15131 return; 240 15132 } 241 15133 } 242 15134 243 15135 // No piece of data specified, dump everything. 244 15136 if (dumpCheckinFormat) { 245 15137 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage); 246 15138 } else if (dumpClient) { 247 15139 ActiveServices.ServiceDumper sdumper; 248 15140 synchronized (this) { 249 15141 mConstants.dump(pw); 250 15142 pw.println(); 251 15143 if (dumpAll) { 252 15144 pw.println("-------------------------------------------------------------------------------"); 253 15145 } 254 15146 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 255 15147 pw.println(); 256 15148 if (dumpAll) { 257 15149 pw.println("-------------------------------------------------------------------------------"); 258 15150 } 259 15151 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 260 15152 pw.println(); 261 15153 if (dumpAll) { 262 15154 pw.println("-------------------------------------------------------------------------------"); 263 15155 } 264 15156 if (dumpAll || dumpPackage != null) { 265 15157 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 266 15158 pw.println(); 267 15159 if (dumpAll) { 268 15160 pw.println("-------------------------------------------------------------------------------"); 269 15161 } 270 15162 } 271 15163 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 272 15164 pw.println(); 273 15165 if (dumpAll) { 274 15166 pw.println("-------------------------------------------------------------------------------"); 275 15167 } 276 15168 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 277 15169 pw.println(); 278 15170 if (dumpAll) { 279 15171 pw.println("-------------------------------------------------------------------------------"); 280 15172 } 281 15173 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, 282 15174 dumpPackage); 283 15175 } 284 15176 sdumper.dumpWithClient(); 285 15177 pw.println(); 286 15178 synchronized (this) { 287 15179 if (dumpAll) { 288 15180 pw.println("-------------------------------------------------------------------------------"); 289 15181 } 290 15182 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 291 15183 pw.println(); 292 15184 if (dumpAll) { 293 15185 pw.println("-------------------------------------------------------------------------------"); 294 15186 } 295 15187 dumpLastANRLocked(pw); 296 15188 pw.println(); 297 15189 if (dumpAll) { 298 15190 pw.println("-------------------------------------------------------------------------------"); 299 15191 } 300 15192 dumpActivityStarterLocked(pw); 301 15193 pw.println(); 302 15194 if (dumpAll) { 303 15195 pw.println("-------------------------------------------------------------------------------"); 304 15196 } 305 15197 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 306 15198 if (mAssociations.size() > 0) { 307 15199 pw.println(); 308 15200 if (dumpAll) { 309 15201 pw.println("-------------------------------------------------------------------------------"); 310 15202 } 311 15203 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 312 15204 } 313 15205 pw.println(); 314 15206 if (dumpAll) { 315 15207 pw.println("-------------------------------------------------------------------------------"); 316 15208 } 317 15209 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 318 15210 } 319 15211 320 15212 } else { 321 15213 synchronized (this) { 322 15214 mConstants.dump(pw); 323 15215 pw.println(); 324 15216 if (dumpAll) { 325 15217 pw.println("-------------------------------------------------------------------------------"); 326 15218 } 327 15219 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 328 15220 pw.println(); 329 15221 if (dumpAll) { 330 15222 pw.println("-------------------------------------------------------------------------------"); 331 15223 } 332 15224 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 333 15225 pw.println(); 334 15226 if (dumpAll) { 335 15227 pw.println("-------------------------------------------------------------------------------"); 336 15228 } 337 15229 if (dumpAll || dumpPackage != null) { 338 15230 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 339 15231 pw.println(); 340 15232 if (dumpAll) { 341 15233 pw.println("-------------------------------------------------------------------------------"); 342 15234 } 343 15235 } 344 15236 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 345 15237 pw.println(); 346 15238 if (dumpAll) { 347 15239 pw.println("-------------------------------------------------------------------------------"); 348 15240 } 349 15241 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 350 15242 pw.println(); 351 15243 if (dumpAll) { 352 15244 pw.println("-------------------------------------------------------------------------------"); 353 15245 } 354 15246 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage) 355 15247 .dumpLocked(); 356 15248 pw.println(); 357 15249 if (dumpAll) { 358 15250 pw.println("-------------------------------------------------------------------------------"); 359 15251 } 360 15252 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 361 15253 pw.println(); 362 15254 if (dumpAll) { 363 15255 pw.println("-------------------------------------------------------------------------------"); 364 15256 } 365 15257 dumpLastANRLocked(pw); 366 15258 pw.println(); 367 15259 if (dumpAll) { 368 15260 pw.println("-------------------------------------------------------------------------------"); 369 15261 } 370 15262 dumpActivityStarterLocked(pw); 371 15263 pw.println(); 372 15264 if (dumpAll) { 373 15265 pw.println("-------------------------------------------------------------------------------"); 374 15266 } 375 15267 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 376 15268 if (mAssociations.size() > 0) { 377 15269 pw.println(); 378 15270 if (dumpAll) { 379 15271 pw.println("-------------------------------------------------------------------------------"); 380 15272 } 381 15273 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 382 15274 } 383 15275 pw.println(); 384 15276 if (dumpAll) { 385 15277 pw.println("-------------------------------------------------------------------------------"); 386 15278 } 387 15279 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 388 15280 } 389 15281 } 390 15282 Binder.restoreCallingIdentity(origId); 391 15283 } 392 15284 393 15285 private void dumpLastANRLocked(PrintWriter pw) { 394 15286 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity lastanr)"); 395 15287 if (mLastANRState == null) { 396 15288 pw.println(" <no ANR has occurred since boot>"); 397 15289 } else { 398 15290 pw.println(mLastANRState); 399 15291 } 400 15292 } 401 15293 402 15294 private void dumpActivityStarterLocked(PrintWriter pw) { 403 15295 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity starter)"); 404 15296 mActivityStarter.dump(pw, ""); 405 15297 } 406 15298 407 15299 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 408 15300 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 409 15301 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage, 410 15302 "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 411 15303 } 412 15304 413 15305 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 414 15306 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) { 415 15307 pw.println(header); 416 15308 417 15309 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 418 15310 dumpPackage); 419 15311 boolean needSep = printedAnything; 420 15312 421 15313 boolean printed = ActivityStackSupervisor.printThisActivity(pw, 422 15314 mStackSupervisor.getResumedActivityLocked(), 423 15315 dumpPackage, needSep, " ResumedActivity: "); 424 15316 if (printed) { 425 15317 printedAnything = true; 426 15318 needSep = false; 427 15319 } 428 15320 429 15321 if (dumpPackage == null) { 430 15322 if (needSep) { 431 15323 pw.println(); 432 15324 } 433 15325 printedAnything = true; 434 15326 mStackSupervisor.dump(pw, " "); 435 15327 } 436 15328 437 15329 if (!printedAnything) { 438 15330 pw.println(" (nothing)"); 439 15331 } 440 15332 } 441 15333 442 15334 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 443 15335 int opti, boolean dumpAll, String dumpPackage) { 444 15336 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)"); 445 15337 446 15338 boolean printedAnything = false; 447 15339 448 15340 if (mRecentTasks != null && mRecentTasks.size() > 0) { 449 15341 boolean printedHeader = false; 450 15342 451 15343 final int N = mRecentTasks.size(); 452 15344 for (int i=0; i<N; i++) { 453 15345 TaskRecord tr = mRecentTasks.get(i); 454 15346 if (dumpPackage != null) { 455 15347 if (tr.realActivity == null || 456 15348 !dumpPackage.equals(tr.realActivity.getPackageName())) { 457 15349 continue; 458 15350 } 459 15351 } 460 15352 if (!printedHeader) { 461 15353 pw.println(" Recent tasks:"); 462 15354 printedHeader = true; 463 15355 printedAnything = true; 464 15356 } 465 15357 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 466 15358 pw.println(tr); 467 15359 if (dumpAll) { 468 15360 mRecentTasks.get(i).dump(pw, " "); 469 15361 } 470 15362 } 471 15363 } 472 15364 473 15365 if (!printedAnything) { 474 15366 pw.println(" (nothing)"); 475 15367 } 476 15368 } 477 15369 478 15370 void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 479 15371 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 480 15372 pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)"); 481 15373 482 15374 int dumpUid = 0; 483 15375 if (dumpPackage != null) { 484 15376 IPackageManager pm = AppGlobals.getPackageManager(); 485 15377 try { 486 15378 dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0); 487 15379 } catch (RemoteException e) { 488 15380 } 489 15381 } 490 15382 491 15383 boolean printedAnything = false; 492 15384 493 15385 final long now = SystemClock.uptimeMillis(); 494 15386 495 15387 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) { 496 15388 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents 497 15389 = mAssociations.valueAt(i1); 498 15390 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) { 499 15391 SparseArray<ArrayMap<String, Association>> sourceUids 500 15392 = targetComponents.valueAt(i2); 501 15393 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) { 502 15394 ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3); 503 15395 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) { 504 15396 Association ass = sourceProcesses.valueAt(i4); 505 15397 if (dumpPackage != null) { 506 15398 if (!ass.mTargetComponent.getPackageName().equals(dumpPackage) 507 15399 && UserHandle.getAppId(ass.mSourceUid) != dumpUid) { 508 15400 continue; 509 15401 } 510 15402 } 511 15403 printedAnything = true; 512 15404 pw.print(" "); 513 15405 pw.print(ass.mTargetProcess); 514 15406 pw.print("/"); 515 15407 UserHandle.formatUid(pw, ass.mTargetUid); 516 15408 pw.print(" <- "); 517 15409 pw.print(ass.mSourceProcess); 518 15410 pw.print("/"); 519 15411 UserHandle.formatUid(pw, ass.mSourceUid); 520 15412 pw.println(); 521 15413 pw.print(" via "); 522 15414 pw.print(ass.mTargetComponent.flattenToShortString()); 523 15415 pw.println(); 524 15416 pw.print(" "); 525 15417 long dur = ass.mTime; 526 15418 if (ass.mNesting > 0) { 527 15419 dur += now - ass.mStartTime; 528 15420 } 529 15421 TimeUtils.formatDuration(dur, pw); 530 15422 pw.print(" ("); 531 15423 pw.print(ass.mCount); 532 15424 pw.print(" times)"); 533 15425 pw.print(" "); 534 15426 for (int i=0; i<ass.mStateTimes.length; i++) { 535 15427 long amt = ass.mStateTimes[i]; 536 15428 if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) { 537 15429 amt += now - ass.mLastStateUptime; 538 15430 } 539 15431 if (amt != 0) { 540 15432 pw.print(" "); 541 15433 pw.print(ProcessList.makeProcStateString( 542 15434 i + ActivityManager.MIN_PROCESS_STATE)); 543 15435 pw.print("="); 544 15436 TimeUtils.formatDuration(amt, pw); 545 15437 if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) { 546 15438 pw.print("*"); 547 15439 } 548 15440 } 549 15441 } 550 15442 pw.println(); 551 15443 if (ass.mNesting > 0) { 552 15444 pw.print(" Currently active: "); 553 15445 TimeUtils.formatDuration(now - ass.mStartTime, pw); 554 15446 pw.println(); 555 15447 } 556 15448 } 557 15449 } 558 15450 } 559 15451 560 15452 } 561 15453 562 15454 if (!printedAnything) { 563 15455 pw.println(" (nothing)"); 564 15456 } 565 15457 } 566 15458 567 15459 boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids, 568 15460 String header, boolean needSep) { 569 15461 boolean printed = false; 570 15462 int whichAppId = -1; 571 15463 if (dumpPackage != null) { 572 15464 try { 573 15465 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 574 15466 dumpPackage, 0); 575 15467 whichAppId = UserHandle.getAppId(info.uid); 576 15468 } catch (NameNotFoundException e) { 577 15469 e.printStackTrace(); 578 15470 } 579 15471 } 580 15472 for (int i=0; i<uids.size(); i++) { 581 15473 UidRecord uidRec = uids.valueAt(i); 582 15474 if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) { 583 15475 continue; 584 15476 } 585 15477 if (!printed) { 586 15478 printed = true; 587 15479 if (needSep) { 588 15480 pw.println(); 589 15481 } 590 15482 pw.print(" "); 591 15483 pw.println(header); 592 15484 needSep = true; 593 15485 } 594 15486 pw.print(" UID "); UserHandle.formatUid(pw, uidRec.uid); 595 15487 pw.print(": "); pw.println(uidRec); 596 15488 } 597 15489 return printed; 598 15490 } 599 15491 600 15492 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 601 15493 int opti, boolean dumpAll, String dumpPackage) { 602 15494 boolean needSep = false; 603 15495 boolean printedAnything = false; 604 15496 int numPers = 0; 605 15497 606 15498 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 607 15499 608 15500 if (dumpAll) { 609 15501 final int NP = mProcessNames.getMap().size(); 610 15502 for (int ip=0; ip<NP; ip++) { 611 15503 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 612 15504 final int NA = procs.size(); 613 15505 for (int ia=0; ia<NA; ia++) { 614 15506 ProcessRecord r = procs.valueAt(ia); 615 15507 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 616 15508 continue; 617 15509 } 618 15510 if (!needSep) { 619 15511 pw.println(" All known processes:"); 620 15512 needSep = true; 621 15513 printedAnything = true; 622 15514 } 623 15515 pw.print(r.persistent ? " *PERS*" : " *APP*"); 624 15516 pw.print(" UID "); pw.print(procs.keyAt(ia)); 625 15517 pw.print(" "); pw.println(r); 626 15518 r.dump(pw, " "); 627 15519 if (r.persistent) { 628 15520 numPers++; 629 15521 } 630 15522 } 631 15523 } 632 15524 } 633 15525 634 15526 if (mIsolatedProcesses.size() > 0) { 635 15527 boolean printed = false; 636 15528 for (int i=0; i<mIsolatedProcesses.size(); i++) { 637 15529 ProcessRecord r = mIsolatedProcesses.valueAt(i); 638 15530 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 639 15531 continue; 640 15532 } 641 15533 if (!printed) { 642 15534 if (needSep) { 643 15535 pw.println(); 644 15536 } 645 15537 pw.println(" Isolated process list (sorted by uid):"); 646 15538 printedAnything = true; 647 15539 printed = true; 648 15540 needSep = true; 649 15541 } 650 15542 pw.print(" Isolated #"); pw.print(i); pw.print(": "); 651 15543 pw.println(r); 652 15544 } 653 15545 } 654 15546 655 15547 if (mActiveInstrumentation.size() > 0) { 656 15548 boolean printed = false; 657 15549 for (int i=0; i<mActiveInstrumentation.size(); i++) { 658 15550 ActiveInstrumentation ai = mActiveInstrumentation.get(i); 659 15551 if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage) 660 15552 && !ai.mTargetInfo.packageName.equals(dumpPackage)) { 661 15553 continue; 662 15554 } 663 15555 if (!printed) { 664 15556 if (needSep) { 665 15557 pw.println(); 666 15558 } 667 15559 pw.println(" Active instrumentation:"); 668 15560 printedAnything = true; 669 15561 printed = true; 670 15562 needSep = true; 671 15563 } 672 15564 pw.print(" Instrumentation #"); pw.print(i); pw.print(": "); 673 15565 pw.println(ai); 674 15566 ai.dump(pw, " "); 675 15567 } 676 15568 } 677 15569 678 15570 if (mActiveUids.size() > 0) { 679 15571 if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) { 680 15572 printedAnything = needSep = true; 681 15573 } 682 15574 } 683 15575 if (dumpAll) { 684 15576 if (mValidateUids.size() > 0) { 685 15577 if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) { 686 15578 printedAnything = needSep = true; 687 15579 } 688 15580 } 689 15581 } 690 15582 691 15583 if (mLruProcesses.size() > 0) { 692 15584 if (needSep) { 693 15585 pw.println(); 694 15586 } 695 15587 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 696 15588 pw.print(" total, non-act at "); 697 15589 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 698 15590 pw.print(", non-svc at "); 699 15591 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 700 15592 pw.println("):"); 701 15593 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 702 15594 needSep = true; 703 15595 printedAnything = true; 704 15596 } 705 15597 706 15598 if (dumpAll || dumpPackage != null) { 707 15599 synchronized (mPidsSelfLocked) { 708 15600 boolean printed = false; 709 15601 for (int i=0; i<mPidsSelfLocked.size(); i++) { 710 15602 ProcessRecord r = mPidsSelfLocked.valueAt(i); 711 15603 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 712 15604 continue; 713 15605 } 714 15606 if (!printed) { 715 15607 if (needSep) pw.println(); 716 15608 needSep = true; 717 15609 pw.println(" PID mappings:"); 718 15610 printed = true; 719 15611 printedAnything = true; 720 15612 } 721 15613 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 722 15614 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 723 15615 } 724 15616 } 725 15617 } 726 15618 727 15619 if (mImportantProcesses.size() > 0) { 728 15620 synchronized (mPidsSelfLocked) { 729 15621 boolean printed = false; 730 15622 for (int i = 0; i< mImportantProcesses.size(); i++) { 731 15623 ProcessRecord r = mPidsSelfLocked.get( 732 15624 mImportantProcesses.valueAt(i).pid); 733 15625 if (dumpPackage != null && (r == null 734 15626 || !r.pkgList.containsKey(dumpPackage))) { 735 15627 continue; 736 15628 } 737 15629 if (!printed) { 738 15630 if (needSep) pw.println(); 739 15631 needSep = true; 740 15632 pw.println(" Foreground Processes:"); 741 15633 printed = true; 742 15634 printedAnything = true; 743 15635 } 744 15636 pw.print(" PID #"); pw.print(mImportantProcesses.keyAt(i)); 745 15637 pw.print(": "); pw.println(mImportantProcesses.valueAt(i)); 746 15638 } 747 15639 } 748 15640 } 749 15641 750 15642 if (mPersistentStartingProcesses.size() > 0) { 751 15643 if (needSep) pw.println(); 752 15644 needSep = true; 753 15645 printedAnything = true; 754 15646 pw.println(" Persisent processes that are starting:"); 755 15647 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 756 15648 "Starting Norm", "Restarting PERS", dumpPackage); 757 15649 } 758 15650 759 15651 if (mRemovedProcesses.size() > 0) { 760 15652 if (needSep) pw.println(); 761 15653 needSep = true; 762 15654 printedAnything = true; 763 15655 pw.println(" Processes that are being removed:"); 764 15656 dumpProcessList(pw, this, mRemovedProcesses, " ", 765 15657 "Removed Norm", "Removed PERS", dumpPackage); 766 15658 } 767 15659 768 15660 if (mProcessesOnHold.size() > 0) { 769 15661 if (needSep) pw.println(); 770 15662 needSep = true; 771 15663 printedAnything = true; 772 15664 pw.println(" Processes that are on old until the system is ready:"); 773 15665 dumpProcessList(pw, this, mProcessesOnHold, " ", 774 15666 "OnHold Norm", "OnHold PERS", dumpPackage); 775 15667 } 776 15668 777 15669 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 778 15670 779 15671 needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage); 780 15672 if (needSep) { 781 15673 printedAnything = true; 782 15674 } 783 15675 784 15676 if (dumpPackage == null) { 785 15677 pw.println(); 786 15678 needSep = false; 787 15679 mUserController.dump(pw, dumpAll); 788 15680 } 789 15681 if (mHomeProcess != null && (dumpPackage == null 790 15682 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 791 15683 if (needSep) { 792 15684 pw.println(); 793 15685 needSep = false; 794 15686 } 795 15687 pw.println(" mHomeProcess: " + mHomeProcess); 796 15688 } 797 15689 if (mPreviousProcess != null && (dumpPackage == null 798 15690 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 799 15691 if (needSep) { 800 15692 pw.println(); 801 15693 needSep = false; 802 15694 } 803 15695 pw.println(" mPreviousProcess: " + mPreviousProcess); 804 15696 } 805 15697 if (dumpAll) { 806 15698 StringBuilder sb = new StringBuilder(128); 807 15699 sb.append(" mPreviousProcessVisibleTime: "); 808 15700 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 809 15701 pw.println(sb); 810 15702 } 811 15703 if (mHeavyWeightProcess != null && (dumpPackage == null 812 15704 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 813 15705 if (needSep) { 814 15706 pw.println(); 815 15707 needSep = false; 816 15708 } 817 15709 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 818 15710 } 819 15711 if (dumpPackage == null) { 820 15712 pw.println(" mGlobalConfiguration: " + getGlobalConfiguration()); 821 15713 mStackSupervisor.dumpDisplayConfigs(pw, " "); 822 15714 } 823 15715 if (dumpAll) { 824 15716 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 825 15717 if (mCompatModePackages.getPackages().size() > 0) { 826 15718 boolean printed = false; 827 15719 for (Map.Entry<String, Integer> entry 828 15720 : mCompatModePackages.getPackages().entrySet()) { 829 15721 String pkg = entry.getKey(); 830 15722 int mode = entry.getValue(); 831 15723 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 832 15724 continue; 833 15725 } 834 15726 if (!printed) { 835 15727 pw.println(" mScreenCompatPackages:"); 836 15728 printed = true; 837 15729 } 838 15730 pw.print(" "); pw.print(pkg); pw.print(": "); 839 15731 pw.print(mode); pw.println(); 840 15732 } 841 15733 } 842 15734 final int NI = mUidObservers.getRegisteredCallbackCount(); 843 15735 boolean printed = false; 844 15736 for (int i=0; i<NI; i++) { 845 15737 final UidObserverRegistration reg = (UidObserverRegistration) 846 15738 mUidObservers.getRegisteredCallbackCookie(i); 847 15739 if (dumpPackage == null || dumpPackage.equals(reg.pkg)) { 848 15740 if (!printed) { 849 15741 pw.println(" mUidObservers:"); 850 15742 printed = true; 851 15743 } 852 15744 pw.print(" "); UserHandle.formatUid(pw, reg.uid); 853 15745 pw.print(" "); pw.print(reg.pkg); pw.print(":"); 854 15746 if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) { 855 15747 pw.print(" IDLE"); 856 15748 } 857 15749 if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) { 858 15750 pw.print(" ACT" ); 859 15751 } 860 15752 if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) { 861 15753 pw.print(" GONE"); 862 15754 } 863 15755 if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) { 864 15756 pw.print(" STATE"); 865 15757 pw.print(" (cut="); pw.print(reg.cutpoint); 866 15758 pw.print(")"); 867 15759 } 868 15760 pw.println(); 869 15761 if (reg.lastProcStates != null) { 870 15762 final int NJ = reg.lastProcStates.size(); 871 15763 for (int j=0; j<NJ; j++) { 872 15764 pw.print(" Last "); 873 15765 UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j)); 874 15766 pw.print(": "); pw.println(reg.lastProcStates.valueAt(j)); 875 15767 } 876 15768 } 877 15769 } 878 15770 } 879 15771 pw.println(" mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist)); 880 15772 pw.println(" mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist)); 881 15773 if (mPendingTempWhitelist.size() > 0) { 882 15774 pw.println(" mPendingTempWhitelist:"); 883 15775 for (int i = 0; i < mPendingTempWhitelist.size(); i++) { 884 15776 PendingTempWhitelist ptw = mPendingTempWhitelist.valueAt(i); 885 15777 pw.print(" "); 886 15778 UserHandle.formatUid(pw, ptw.targetUid); 887 15779 pw.print(": "); 888 15780 TimeUtils.formatDuration(ptw.duration, pw); 889 15781 pw.print(" "); 890 15782 pw.println(ptw.tag); 891 15783 } 892 15784 } 893 15785 } 894 15786 if (dumpPackage == null) { 895 15787 pw.println(" mWakefulness=" 896 15788 + PowerManagerInternal.wakefulnessToString(mWakefulness)); 897 15789 pw.println(" mSleepTokens=" + mSleepTokens); 898 15790 pw.println(" mSleeping=" + mSleeping); 899 15791 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode); 900 15792 if (mRunningVoice != null) { 901 15793 pw.println(" mRunningVoice=" + mRunningVoice); 902 15794 pw.println(" mVoiceWakeLock" + mVoiceWakeLock); 903 15795 } 904 15796 } 905 15797 pw.println(" mVrController=" + mVrController); 906 15798 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 907 15799 || mOrigWaitForDebugger) { 908 15800 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 909 15801 || dumpPackage.equals(mOrigDebugApp)) { 910 15802 if (needSep) { 911 15803 pw.println(); 912 15804 needSep = false; 913 15805 } 914 15806 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 915 15807 + " mDebugTransient=" + mDebugTransient 916 15808 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 917 15809 } 918 15810 } 919 15811 if (mCurAppTimeTracker != null) { 920 15812 mCurAppTimeTracker.dumpWithHeader(pw, " ", true); 921 15813 } 922 15814 if (mMemWatchProcesses.getMap().size() > 0) { 923 15815 pw.println(" Mem watch processes:"); 924 15816 final ArrayMap<String, SparseArray<Pair<Long, String>>> procs 925 15817 = mMemWatchProcesses.getMap(); 926 15818 for (int i=0; i<procs.size(); i++) { 927 15819 final String proc = procs.keyAt(i); 928 15820 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i); 929 15821 for (int j=0; j<uids.size(); j++) { 930 15822 if (needSep) { 931 15823 pw.println(); 932 15824 needSep = false; 933 15825 } 934 15826 StringBuilder sb = new StringBuilder(); 935 15827 sb.append(" ").append(proc).append('/'); 936 15828 UserHandle.formatUid(sb, uids.keyAt(j)); 937 15829 Pair<Long, String> val = uids.valueAt(j); 938 15830 sb.append(": "); DebugUtils.sizeValueToString(val.first, sb); 939 15831 if (val.second != null) { 940 15832 sb.append(", report to ").append(val.second); 941 15833 } 942 15834 pw.println(sb.toString()); 943 15835 } 944 15836 } 945 15837 pw.print(" mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName); 946 15838 pw.print(" mMemWatchDumpFile="); pw.println(mMemWatchDumpFile); 947 15839 pw.print(" mMemWatchDumpPid="); pw.print(mMemWatchDumpPid); 948 15840 pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid); 949 15841 } 950 15842 if (mTrackAllocationApp != null) { 951 15843 if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) { 952 15844 if (needSep) { 953 15845 pw.println(); 954 15846 needSep = false; 955 15847 } 956 15848 pw.println(" mTrackAllocationApp=" + mTrackAllocationApp); 957 15849 } 958 15850 } 959 15851 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 960 15852 || mProfileFd != null) { 961 15853 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 962 15854 if (needSep) { 963 15855 pw.println(); 964 15856 needSep = false; 965 15857 } 966 15858 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 967 15859 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 968 15860 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 969 15861 + mAutoStopProfiler + " mStreamingOutput=" + mStreamingOutput); 970 15862 pw.println(" mProfileType=" + mProfileType); 971 15863 } 972 15864 } 973 15865 if (mNativeDebuggingApp != null) { 974 15866 if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) { 975 15867 if (needSep) { 976 15868 pw.println(); 977 15869 needSep = false; 978 15870 } 979 15871 pw.println(" mNativeDebuggingApp=" + mNativeDebuggingApp); 980 15872 } 981 15873 } 982 15874 if (dumpPackage == null) { 983 15875 if (mAlwaysFinishActivities) { 984 15876 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities); 985 15877 } 986 15878 if (mController != null) { 987 15879 pw.println(" mController=" + mController 988 15880 + " mControllerIsAMonkey=" + mControllerIsAMonkey); 989 15881 } 990 15882 if (dumpAll) { 991 15883 pw.println(" Total persistent processes: " + numPers); 992 15884 pw.println(" mProcessesReady=" + mProcessesReady 993 15885 + " mSystemReady=" + mSystemReady 994 15886 + " mBooted=" + mBooted 995 15887 + " mFactoryTest=" + mFactoryTest); 996 15888 pw.println(" mBooting=" + mBooting 997 15889 + " mCallFinishBooting=" + mCallFinishBooting 998 15890 + " mBootAnimationComplete=" + mBootAnimationComplete); 999 15891 pw.print(" mLastPowerCheckRealtime="); 1000 15892 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 1001 15893 pw.println(""); 1002 15894 pw.print(" mLastPowerCheckUptime="); 1003 15895 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 1004 15896 pw.println(""); 1005 15897 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 1006 15898 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 1007 15899 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 1008 15900 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 1009 15901 + " (" + mLruProcesses.size() + " total)" 1010 15902 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 1011 15903 + " mNumServiceProcs=" + mNumServiceProcs 1012 15904 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 1013 15905 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 1014 15906 + " mLastMemoryLevel=" + mLastMemoryLevel 1015 15907 + " mLastNumProcesses=" + mLastNumProcesses); 1016 15908 long now = SystemClock.uptimeMillis(); 1017 15909 pw.print(" mLastIdleTime="); 1018 15910 TimeUtils.formatDuration(now, mLastIdleTime, pw); 1019 15911 pw.print(" mLowRamSinceLastIdle="); 1020 15912 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 1021 15913 pw.println(); 1022 15914 } 1023 15915 } 1024 15916 1025 15917 if (!printedAnything) { 1026 15918 pw.println(" (nothing)"); 1027 15919 } 1028 15920 } 1029 15921 1030 15922 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 1031 15923 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 1032 15924 if (mProcessesToGc.size() > 0) { 1033 15925 boolean printed = false; 1034 15926 long now = SystemClock.uptimeMillis(); 1035 15927 for (int i=0; i<mProcessesToGc.size(); i++) { 1036 15928 ProcessRecord proc = mProcessesToGc.get(i); 1037 15929 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 1038 15930 continue; 1039 15931 } 1040 15932 if (!printed) { 1041 15933 if (needSep) pw.println(); 1042 15934 needSep = true; 1043 15935 pw.println(" Processes that are waiting to GC:"); 1044 15936 printed = true; 1045 15937 } 1046 15938 pw.print(" Process "); pw.println(proc); 1047 15939 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 1048 15940 pw.print(", last gced="); 1049 15941 pw.print(now-proc.lastRequestedGc); 1050 15942 pw.print(" ms ago, last lowMem="); 1051 15943 pw.print(now-proc.lastLowMemory); 1052 15944 pw.println(" ms ago"); 1053 15945 1054 15946 } 1055 15947 } 1056 15948 return needSep; 1057 15949 } 1058 15950 1059 15951 void printOomLevel(PrintWriter pw, String name, int adj) { 1060 15952 pw.print(" "); 1061 15953 if (adj >= 0) { 1062 15954 pw.print(' '); 1063 15955 if (adj < 10) pw.print(' '); 1064 15956 } else { 1065 15957 if (adj > -10) pw.print(' '); 1066 15958 } 1067 15959 pw.print(adj); 1068 15960 pw.print(": "); 1069 15961 pw.print(name); 1070 15962 pw.print(" ("); 1071 15963 pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024)); 1072 15964 pw.println(")"); 1073 15965 } 1074 15966 1075 15967 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 1076 15968 int opti, boolean dumpAll) { 1077 15969 boolean needSep = false; 1078 15970 1079 15971 if (mLruProcesses.size() > 0) { 1080 15972 if (needSep) pw.println(); 1081 15973 needSep = true; 1082 15974 pw.println(" OOM levels:"); 1083 15975 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 1084 15976 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 1085 15977 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ); 1086 15978 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 1087 15979 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 1088 15980 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 1089 15981 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 1090 15982 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 1091 15983 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 1092 15984 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 1093 15985 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 1094 15986 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 1095 15987 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 1096 15988 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 1097 15989 1098 15990 if (needSep) pw.println(); 1099 15991 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 1100 15992 pw.print(" total, non-act at "); 1101 15993 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 1102 15994 pw.print(", non-svc at "); 1103 15995 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 1104 15996 pw.println("):"); 1105 15997 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 1106 15998 needSep = true; 1107 15999 } 1108 16000 1109 16001 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 1110 16002 1111 16003 pw.println(); 1112 16004 pw.println(" mHomeProcess: " + mHomeProcess); 1113 16005 pw.println(" mPreviousProcess: " + mPreviousProcess); 1114 16006 if (mHeavyWeightProcess != null) { 1115 16007 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 1116 16008 } 1117 16009 1118 16010 return true; 1119 16011 } 1120 16012 1121 16013 /** 1122 16014 * There are three ways to call this: 1123 16015 * - no provider specified: dump all the providers 1124 16016 * - a flattened component name that matched an existing provider was specified as the 1125 16017 * first arg: dump that one provider 1126 16018 * - the first arg isn't the flattened component name of an existing provider: 1127 16019 * dump all providers whose component contains the first arg as a substring 1128 16020 */ 1129 16021 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 1130 16022 int opti, boolean dumpAll) { 1131 16023 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 1132 16024 } 1133 16025 1134 16026 static class ItemMatcher { 1135 16027 ArrayList<ComponentName> components; 1136 16028 ArrayList<String> strings; 1137 16029 ArrayList<Integer> objects; 1138 16030 boolean all; 1139 16031 1140 16032 ItemMatcher() { 1141 16033 all = true; 1142 16034 } 1143 16035 1144 16036 void build(String name) { 1145 16037 ComponentName componentName = ComponentName.unflattenFromString(name); 1146 16038 if (componentName != null) { 1147 16039 if (components == null) { 1148 16040 components = new ArrayList<ComponentName>(); 1149 16041 } 1150 16042 components.add(componentName); 1151 16043 all = false; 1152 16044 } else { 1153 16045 int objectId = 0; 1154 16046 // Not a '/' separated full component name; maybe an object ID? 1155 16047 try { 1156 16048 objectId = Integer.parseInt(name, 16); 1157 16049 if (objects == null) { 1158 16050 objects = new ArrayList<Integer>(); 1159 16051 } 1160 16052 objects.add(objectId); 1161 16053 all = false; 1162 16054 } catch (RuntimeException e) { 1163 16055 // Not an integer; just do string match. 1164 16056 if (strings == null) { 1165 16057 strings = new ArrayList<String>(); 1166 16058 } 1167 16059 strings.add(name); 1168 16060 all = false; 1169 16061 } 1170 16062 } 1171 16063 } 1172 16064 1173 16065 int build(String[] args, int opti) { 1174 16066 for (; opti<args.length; opti++) { 1175 16067 String name = args[opti]; 1176 16068 if ("--".equals(name)) { 1177 16069 return opti+1; 1178 16070 } 1179 16071 build(name); 1180 16072 } 1181 16073 return opti; 1182 16074 } 1183 16075 1184 16076 boolean match(Object object, ComponentName comp) { 1185 16077 if (all) { 1186 16078 return true; 1187 16079 } 1188 16080 if (components != null) { 1189 16081 for (int i=0; i<components.size(); i++) { 1190 16082 if (components.get(i).equals(comp)) { 1191 16083 return true; 1192 16084 } 1193 16085 } 1194 16086 } 1195 16087 if (objects != null) { 1196 16088 for (int i=0; i<objects.size(); i++) { 1197 16089 if (System.identityHashCode(object) == objects.get(i)) { 1198 16090 return true; 1199 16091 } 1200 16092 } 1201 16093 } 1202 16094 if (strings != null) { 1203 16095 String flat = comp.flattenToString(); 1204 16096 for (int i=0; i<strings.size(); i++) { 1205 16097 if (flat.contains(strings.get(i))) { 1206 16098 return true; 1207 16099 } 1208 16100 } 1209 16101 } 1210 16102 return false; 1211 16103 } 1212 16104 } 1213 16105 1214 16106 /** 1215 16107 * There are three things that cmd can be: 1216 16108 * - a flattened component name that matches an existing activity 1217 16109 * - the cmd arg isn't the flattened component name of an existing activity: 1218 16110 * dump all activity whose component contains the cmd as a substring 1219 16111 * - A hex number of the ActivityRecord object instance. 1220 16112 * 1221 16113 * @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack 1222 16114 * @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack 1223 16115 */ 1224 16116 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 1225 16117 int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) { 1226 16118 ArrayList<ActivityRecord> activities; 1227 16119 1228 16120 synchronized (this) { 1229 16121 activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly, 1230 16122 dumpFocusedStackOnly); 1231 16123 } 1232 16124 1233 16125 if (activities.size() <= 0) { 1234 16126 return false; 1235 16127 } 1236 16128 1237 16129 String[] newArgs = new String[args.length - opti]; 1238 16130 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 1239 16131 1240 16132 TaskRecord lastTask = null; 1241 16133 boolean needSep = false; 1242 16134 for (int i=activities.size()-1; i>=0; i--) { 1243 16135 ActivityRecord r = activities.get(i); 1244 16136 if (needSep) { 1245 16137 pw.println(); 1246 16138 } 1247 16139 needSep = true; 1248 16140 synchronized (this) { 1249 16141 final TaskRecord task = r.getTask(); 1250 16142 if (lastTask != task) { 1251 16143 lastTask = task; 1252 16144 pw.print("TASK "); pw.print(lastTask.affinity); 1253 16145 pw.print(" id="); pw.print(lastTask.taskId); 1254 16146 pw.print(" userId="); pw.println(lastTask.userId); 1255 16147 if (dumpAll) { 1256 16148 lastTask.dump(pw, " "); 1257 16149 } 1258 16150 } 1259 16151 } 1260 16152 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 1261 16153 } 1262 16154 return true; 1263 16155 } 1264 16156 1265 16157 /** 1266 16158 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 1267 16159 * there is a thread associated with the activity. 1268 16160 */ 1269 16161 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 1270 16162 final ActivityRecord r, String[] args, boolean dumpAll) { 1271 16163 String innerPrefix = prefix + " "; 1272 16164 synchronized (this) { 1273 16165 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 1274 16166 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 1275 16167 pw.print(" pid="); 1276 16168 if (r.app != null) pw.println(r.app.pid); 1277 16169 else pw.println("(not running)"); 1278 16170 if (dumpAll) { 1279 16171 r.dump(pw, innerPrefix); 1280 16172 } 1281 16173 } 1282 16174 if (r.app != null && r.app.thread != null) { 1283 16175 // flush anything that is already in the PrintWriter since the thread is going 1284 16176 // to write to the file descriptor directly 1285 16177 pw.flush(); 1286 16178 try { 1287 16179 TransferPipe tp = new TransferPipe(); 1288 16180 try { 1289 16181 r.app.thread.dumpActivity(tp.getWriteFd(), 1290 16182 r.appToken, innerPrefix, args); 1291 16183 tp.go(fd); 1292 16184 } finally { 1293 16185 tp.kill(); 1294 16186 } 1295 16187 } catch (IOException e) { 1296 16188 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 1297 16189 } catch (RemoteException e) { 1298 16190 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 1299 16191 } 1300 16192 } 1301 16193 } 1302 16194 1303 16195 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 1304 16196 int opti, boolean dumpAll, String dumpPackage) { 1305 16197 boolean needSep = false; 1306 16198 boolean onlyHistory = false; 1307 16199 boolean printedAnything = false; 1308 16200 1309 16201 if ("history".equals(dumpPackage)) { 1310 16202 if (opti < args.length && "-s".equals(args[opti])) { 1311 16203 dumpAll = false; 1312 16204 } 1313 16205 onlyHistory = true; 1314 16206 dumpPackage = null; 1315 16207 } 1316 16208 1317 16209 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 1318 16210 if (!onlyHistory && dumpAll) { 1319 16211 if (mRegisteredReceivers.size() > 0) { 1320 16212 boolean printed = false; 1321 16213 Iterator it = mRegisteredReceivers.values().iterator(); 1322 16214 while (it.hasNext()) { 1323 16215 ReceiverList r = (ReceiverList)it.next(); 1324 16216 if (dumpPackage != null && (r.app == null || 1325 16217 !dumpPackage.equals(r.app.info.packageName))) { 1326 16218 continue; 1327 16219 } 1328 16220 if (!printed) { 1329 16221 pw.println(" Registered Receivers:"); 1330 16222 needSep = true; 1331 16223 printed = true; 1332 16224 printedAnything = true; 1333 16225 } 1334 16226 pw.print(" * "); pw.println(r); 1335 16227 r.dump(pw, " "); 1336 16228 } 1337 16229 } 1338 16230 1339 16231 if (mReceiverResolver.dump(pw, needSep ? 1340 16232 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 1341 16233 " ", dumpPackage, false, false)) { 1342 16234 needSep = true; 1343 16235 printedAnything = true; 1344 16236 } 1345 16237 } 1346 16238 1347 16239 for (BroadcastQueue q : mBroadcastQueues) { 1348 16240 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 1349 16241 printedAnything |= needSep; 1350 16242 } 1351 16243 1352 16244 needSep = true; 1353 16245 1354 16246 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 1355 16247 for (int user=0; user<mStickyBroadcasts.size(); user++) { 1356 16248 if (needSep) { 1357 16249 pw.println(); 1358 16250 } 1359 16251 needSep = true; 1360 16252 printedAnything = true; 1361 16253 pw.print(" Sticky broadcasts for user "); 1362 16254 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 1363 16255 StringBuilder sb = new StringBuilder(128); 1364 16256 for (Map.Entry<String, ArrayList<Intent>> ent 1365 16257 : mStickyBroadcasts.valueAt(user).entrySet()) { 1366 16258 pw.print(" * Sticky action "); pw.print(ent.getKey()); 1367 16259 if (dumpAll) { 1368 16260 pw.println(":"); 1369 16261 ArrayList<Intent> intents = ent.getValue(); 1370 16262 final int N = intents.size(); 1371 16263 for (int i=0; i<N; i++) { 1372 16264 sb.setLength(0); 1373 16265 sb.append(" Intent: "); 1374 16266 intents.get(i).toShortString(sb, false, true, false, false); 1375 16267 pw.println(sb.toString()); 1376 16268 Bundle bundle = intents.get(i).getExtras(); 1377 16269 if (bundle != null) { 1378 16270 pw.print(" "); 1379 16271 pw.println(bundle.toString()); 1380 16272 } 1381 16273 } 1382 16274 } else { 1383 16275 pw.println(""); 1384 16276 } 1385 16277 } 1386 16278 } 1387 16279 } 1388 16280 1389 16281 if (!onlyHistory && dumpAll) { 1390 16282 pw.println(); 1391 16283 for (BroadcastQueue queue : mBroadcastQueues) { 1392 16284 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 1393 16285 + queue.mBroadcastsScheduled); 1394 16286 } 1395 16287 pw.println(" mHandler:"); 1396 16288 mHandler.dump(new PrintWriterPrinter(pw), " "); 1397 16289 needSep = true; 1398 16290 printedAnything = true; 1399 16291 } 1400 16292 1401 16293 if (!printedAnything) { 1402 16294 pw.println(" (nothing)"); 1403 16295 } 1404 16296 } 1405 16297 1406 16298 void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 1407 16299 int opti, boolean dumpAll, String dumpPackage) { 1408 16300 if (mCurBroadcastStats == null) { 1409 16301 return; 1410 16302 } 1411 16303 1412 16304 pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)"); 1413 16305 final long now = SystemClock.elapsedRealtime(); 1414 16306 if (mLastBroadcastStats != null) { 1415 16307 pw.print(" Last stats (from "); 1416 16308 TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw); 1417 16309 pw.print(" to "); 1418 16310 TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw); 1419 16311 pw.print(", "); 1420 16312 TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime 1421 16313 - mLastBroadcastStats.mStartUptime, pw); 1422 16314 pw.println(" uptime):"); 1423 16315 if (!mLastBroadcastStats.dumpStats(pw, " ", dumpPackage)) { 1424 16316 pw.println(" (nothing)"); 1425 16317 } 1426 16318 pw.println(); 1427 16319 } 1428 16320 pw.print(" Current stats (from "); 1429 16321 TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw); 1430 16322 pw.print(" to now, "); 1431 16323 TimeUtils.formatDuration(SystemClock.uptimeMillis() 1432 16324 - mCurBroadcastStats.mStartUptime, pw); 1433 16325 pw.println(" uptime):"); 1434 16326 if (!mCurBroadcastStats.dumpStats(pw, " ", dumpPackage)) { 1435 16327 pw.println(" (nothing)"); 1436 16328 } 1437 16329 } 1438 16330 1439 16331 void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args, 1440 16332 int opti, boolean fullCheckin, String dumpPackage) { 1441 16333 if (mCurBroadcastStats == null) { 1442 16334 return; 1443 16335 } 1444 16336 1445 16337 if (mLastBroadcastStats != null) { 1446 16338 mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage); 1447 16339 if (fullCheckin) { 1448 16340 mLastBroadcastStats = null; 1449 16341 return; 1450 16342 } 1451 16343 } 1452 16344 mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage); 1453 16345 if (fullCheckin) { 1454 16346 mCurBroadcastStats = null; 1455 16347 } 1456 16348 } 1457 16349 1458 16350 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 1459 16351 int opti, boolean dumpAll, String dumpPackage) { 1460 16352 boolean needSep; 1461 16353 boolean printedAnything = false; 1462 16354 1463 16355 ItemMatcher matcher = new ItemMatcher(); 1464 16356 matcher.build(args, opti); 1465 16357 1466 16358 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 1467 16359 1468 16360 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 1469 16361 printedAnything |= needSep; 1470 16362 1471 16363 if (mLaunchingProviders.size() > 0) { 1472 16364 boolean printed = false; 1473 16365 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 1474 16366 ContentProviderRecord r = mLaunchingProviders.get(i); 1475 16367 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 1476 16368 continue; 1477 16369 } 1478 16370 if (!printed) { 1479 16371 if (needSep) pw.println(); 1480 16372 needSep = true; 1481 16373 pw.println(" Launching content providers:"); 1482 16374 printed = true; 1483 16375 printedAnything = true; 1484 16376 } 1485 16377 pw.print(" Launching #"); pw.print(i); pw.print(": "); 1486 16378 pw.println(r); 1487 16379 } 1488 16380 } 1489 16381 1490 16382 if (!printedAnything) { 1491 16383 pw.println(" (nothing)"); 1492 16384 } 1493 16385 } 1494 16386 1495 16387 void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 1496 16388 int opti, boolean dumpAll, String dumpPackage) { 1497 16389 boolean needSep = false; 1498 16390 boolean printedAnything = false; 1499 16391 1500 16392 pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)"); 1501 16393 1502 16394 if (mGrantedUriPermissions.size() > 0) { 1503 16395 boolean printed = false; 1504 16396 int dumpUid = -2; 1505 16397 if (dumpPackage != null) { 1506 16398 try { 1507 16399 dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage, 1508 16400 MATCH_ANY_USER, 0); 1509 16401 } catch (NameNotFoundException e) { 1510 16402 dumpUid = -1; 1511 16403 } 1512 16404 } 1513 16405 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 1514 16406 int uid = mGrantedUriPermissions.keyAt(i); 1515 16407 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 1516 16408 continue; 1517 16409 } 1518 16410 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 1519 16411 if (!printed) { 1520 16412 if (needSep) pw.println(); 1521 16413 needSep = true; 1522 16414 pw.println(" Granted Uri Permissions:"); 1523 16415 printed = true; 1524 16416 printedAnything = true; 1525 16417 } 1526 16418 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 1527 16419 for (UriPermission perm : perms.values()) { 1528 16420 pw.print(" "); pw.println(perm); 1529 16421 if (dumpAll) { 1530 16422 perm.dump(pw, " "); 1531 16423 } 1532 16424 } 1533 16425 } 1534 16426 } 1535 16427 1536 16428 if (!printedAnything) { 1537 16429 pw.println(" (nothing)"); 1538 16430 } 1539 16431 } 1540 16432 1541 16433 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 1542 16434 int opti, boolean dumpAll, String dumpPackage) { 1543 16435 boolean printed = false; 1544 16436 1545 16437 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 1546 16438 1547 16439 if (mIntentSenderRecords.size() > 0) { 1548 16440 // Organize these by package name, so they are easier to read. 1549 16441 final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>(); 1550 16442 final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>(); 1551 16443 final Iterator<WeakReference<PendingIntentRecord>> it 1552 16444 = mIntentSenderRecords.values().iterator(); 1553 16445 while (it.hasNext()) { 1554 16446 WeakReference<PendingIntentRecord> ref = it.next(); 1555 16447 PendingIntentRecord rec = ref != null ? ref.get() : null; 1556 16448 if (rec == null) { 1557 16449 weakRefs.add(ref); 1558 16450 continue; 1559 16451 } 1560 16452 if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) { 1561 16453 continue; 1562 16454 } 1563 16455 ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName); 1564 16456 if (list == null) { 1565 16457 list = new ArrayList<>(); 1566 16458 byPackage.put(rec.key.packageName, list); 1567 16459 } 1568 16460 list.add(rec); 1569 16461 } 1570 16462 for (int i = 0; i < byPackage.size(); i++) { 1571 16463 ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i); 1572 16464 printed = true; 1573 16465 pw.print(" * "); pw.print(byPackage.keyAt(i)); 1574 16466 pw.print(": "); pw.print(intents.size()); pw.println(" items"); 1575 16467 for (int j = 0; j < intents.size(); j++) { 1576 16468 pw.print(" #"); pw.print(j); pw.print(": "); pw.println(intents.get(j)); 1577 16469 if (dumpAll) { 1578 16470 intents.get(j).dump(pw, " "); 1579 16471 } 1580 16472 } 1581 16473 } 1582 16474 if (weakRefs.size() > 0) { 1583 16475 printed = true; 1584 16476 pw.println(" * WEAK REFS:"); 1585 16477 for (int i = 0; i < weakRefs.size(); i++) { 1586 16478 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i)); 1587 16479 } 1588 16480 } 1589 16481 } 1590 16482 1591 16483 if (!printed) { 1592 16484 pw.println(" (nothing)"); 1593 16485 } 1594 16486 } 1595 16487 1596 16488 private static final int dumpProcessList(PrintWriter pw, 1597 16489 ActivityManagerService service, List list, 1598 16490 String prefix, String normalLabel, String persistentLabel, 1599 16491 String dumpPackage) { 1600 16492 int numPers = 0; 1601 16493 final int N = list.size()-1; 1602 16494 for (int i=N; i>=0; i--) { 1603 16495 ProcessRecord r = (ProcessRecord)list.get(i); 1604 16496 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 1605 16497 continue; 1606 16498 } 1607 16499 pw.println(String.format("%s%s #%2d: %s", 1608 16500 prefix, (r.persistent ? persistentLabel : normalLabel), 1609 16501 i, r.toString())); 1610 16502 if (r.persistent) { 1611 16503 numPers++; 1612 16504 } 1613 16505 } 1614 16506 return numPers; 1615 16507 } 1616 16508 1617 16509 private static final boolean dumpProcessOomList(PrintWriter pw, 1618 16510 ActivityManagerService service, List<ProcessRecord> origList, 1619 16511 String prefix, String normalLabel, String persistentLabel, 1620 16512 boolean inclDetails, String dumpPackage) { 1621 16513 1622 16514 ArrayList<Pair<ProcessRecord, Integer>> list 1623 16515 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 1624 16516 for (int i=0; i<origList.size(); i++) { 1625 16517 ProcessRecord r = origList.get(i); 1626 16518 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 1627 16519 continue; 1628 16520 } 1629 16521 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 1630 16522 } 1631 16523 1632 16524 if (list.size() <= 0) { 1633 16525 return false; 1634 16526 } 1635 16527 1636 16528 Comparator<Pair<ProcessRecord, Integer>> comparator 1637 16529 = new Comparator<Pair<ProcessRecord, Integer>>() { 1638 16530 @Override 1639 16531 public int compare(Pair<ProcessRecord, Integer> object1, 1640 16532 Pair<ProcessRecord, Integer> object2) { 1641 16533 if (object1.first.setAdj != object2.first.setAdj) { 1642 16534 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 1643 16535 } 1644 16536 if (object1.first.setProcState != object2.first.setProcState) { 1645 16537 return object1.first.setProcState > object2.first.setProcState ? -1 : 1; 1646 16538 } 1647 16539 if (object1.second.intValue() != object2.second.intValue()) { 1648 16540 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 1649 16541 } 1650 16542 return 0; 1651 16543 } 1652 16544 }; 1653 16545 1654 16546 Collections.sort(list, comparator); 1655 16547 1656 16548 final long curRealtime = SystemClock.elapsedRealtime(); 1657 16549 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 1658 16550 final long curUptime = SystemClock.uptimeMillis(); 1659 16551 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 1660 16552 1661 16553 for (int i=list.size()-1; i>=0; i--) { 1662 16554 ProcessRecord r = list.get(i).first; 1663 16555 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 1664 16556 char schedGroup; 1665 16557 switch (r.setSchedGroup) { 1666 16558 case ProcessList.SCHED_GROUP_BACKGROUND: 1667 16559 schedGroup = 'B'; 1668 16560 break; 1669 16561 case ProcessList.SCHED_GROUP_DEFAULT: 1670 16562 schedGroup = 'F'; 1671 16563 break; 1672 16564 case ProcessList.SCHED_GROUP_TOP_APP: 1673 16565 schedGroup = 'T'; 1674 16566 break; 1675 16567 default: 1676 16568 schedGroup = '?'; 1677 16569 break; 1678 16570 } 1679 16571 char foreground; 1680 16572 if (r.foregroundActivities) { 1681 16573 foreground = 'A'; 1682 16574 } else if (r.foregroundServices) { 1683 16575 foreground = 'S'; 1684 16576 } else { 1685 16577 foreground = ' '; 1686 16578 } 1687 16579 String procState = ProcessList.makeProcStateString(r.curProcState); 1688 16580 pw.print(prefix); 1689 16581 pw.print(r.persistent ? persistentLabel : normalLabel); 1690 16582 pw.print(" #"); 1691 16583 int num = (origList.size()-1)-list.get(i).second; 1692 16584 if (num < 10) pw.print(' '); 1693 16585 pw.print(num); 1694 16586 pw.print(": "); 1695 16587 pw.print(oomAdj); 1696 16588 pw.print(' '); 1697 16589 pw.print(schedGroup); 1698 16590 pw.print('/'); 1699 16591 pw.print(foreground); 1700 16592 pw.print('/'); 1701 16593 pw.print(procState); 1702 16594 pw.print(" trm:"); 1703 16595 if (r.trimMemoryLevel < 10) pw.print(' '); 1704 16596 pw.print(r.trimMemoryLevel); 1705 16597 pw.print(' '); 1706 16598 pw.print(r.toShortString()); 1707 16599 pw.print(" ("); 1708 16600 pw.print(r.adjType); 1709 16601 pw.println(')'); 1710 16602 if (r.adjSource != null || r.adjTarget != null) { 1711 16603 pw.print(prefix); 1712 16604 pw.print(" "); 1713 16605 if (r.adjTarget instanceof ComponentName) { 1714 16606 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 1715 16607 } else if (r.adjTarget != null) { 1716 16608 pw.print(r.adjTarget.toString()); 1717 16609 } else { 1718 16610 pw.print("{null}"); 1719 16611 } 1720 16612 pw.print("<="); 1721 16613 if (r.adjSource instanceof ProcessRecord) { 1722 16614 pw.print("Proc{"); 1723 16615 pw.print(((ProcessRecord)r.adjSource).toShortString()); 1724 16616 pw.println("}"); 1725 16617 } else if (r.adjSource != null) { 1726 16618 pw.println(r.adjSource.toString()); 1727 16619 } else { 1728 16620 pw.println("{null}"); 1729 16621 } 1730 16622 } 1731 16623 if (inclDetails) { 1732 16624 pw.print(prefix); 1733 16625 pw.print(" "); 1734 16626 pw.print("oom: max="); pw.print(r.maxAdj); 1735 16627 pw.print(" curRaw="); pw.print(r.curRawAdj); 1736 16628 pw.print(" setRaw="); pw.print(r.setRawAdj); 1737 16629 pw.print(" cur="); pw.print(r.curAdj); 1738 16630 pw.print(" set="); pw.println(r.setAdj); 1739 16631 pw.print(prefix); 1740 16632 pw.print(" "); 1741 16633 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 1742 16634 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 1743 16635 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024); 1744 16636 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024); 1745 16637 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024); 1746 16638 pw.println(); 1747 16639 pw.print(prefix); 1748 16640 pw.print(" "); 1749 16641 pw.print("cached="); pw.print(r.cached); 1750 16642 pw.print(" empty="); pw.print(r.empty); 1751 16643 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 1752 16644 1753 16645 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 1754 16646 if (r.lastWakeTime != 0) { 1755 16647 long wtime; 1756 16648 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 1757 16649 synchronized (stats) { 1758 16650 wtime = stats.getProcessWakeTime(r.info.uid, 1759 16651 r.pid, curRealtime); 1760 16652 } 1761 16653 long timeUsed = wtime - r.lastWakeTime; 1762 16654 pw.print(prefix); 1763 16655 pw.print(" "); 1764 16656 pw.print("keep awake over "); 1765 16657 TimeUtils.formatDuration(realtimeSince, pw); 1766 16658 pw.print(" used "); 1767 16659 TimeUtils.formatDuration(timeUsed, pw); 1768 16660 pw.print(" ("); 1769 16661 pw.print((timeUsed*100)/realtimeSince); 1770 16662 pw.println("%)"); 1771 16663 } 1772 16664 if (r.lastCpuTime != 0) { 1773 16665 long timeUsed = r.curCpuTime - r.lastCpuTime; 1774 16666 pw.print(prefix); 1775 16667 pw.print(" "); 1776 16668 pw.print("run cpu over "); 1777 16669 TimeUtils.formatDuration(uptimeSince, pw); 1778 16670 pw.print(" used "); 1779 16671 TimeUtils.formatDuration(timeUsed, pw); 1780 16672 pw.print(" ("); 1781 16673 pw.print((timeUsed*100)/uptimeSince); 1782 16674 pw.println("%)"); 1783 16675 } 1784 16676 } 1785 16677 } 1786 16678 } 1787 16679 return true; 1788 16680 } 1789 16681 1790 16682 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs, 1791 16683 String[] args) { 1792 16684 ArrayList<ProcessRecord> procs; 1793 16685 synchronized (this) { 1794 16686 if (args != null && args.length > start 1795 16687 && args[start].charAt(0) != '-') { 1796 16688 procs = new ArrayList<ProcessRecord>(); 1797 16689 int pid = -1; 1798 16690 try { 1799 16691 pid = Integer.parseInt(args[start]); 1800 16692 } catch (NumberFormatException e) { 1801 16693 } 1802 16694 for (int i=mLruProcesses.size()-1; i>=0; i--) { 1803 16695 ProcessRecord proc = mLruProcesses.get(i); 1804 16696 if (proc.pid == pid) { 1805 16697 procs.add(proc); 1806 16698 } else if (allPkgs && proc.pkgList != null 1807 16699 && proc.pkgList.containsKey(args[start])) { 1808 16700 procs.add(proc); 1809 16701 } else if (proc.processName.equals(args[start])) { 1810 16702 procs.add(proc); 1811 16703 } 1812 16704 } 1813 16705 if (procs.size() <= 0) { 1814 16706 return null; 1815 16707 } 1816 16708 } else { 1817 16709 procs = new ArrayList<ProcessRecord>(mLruProcesses); 1818 16710 } 1819 16711 } 1820 16712 return procs; 1821 16713 } 1822 16714 1823 16715 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 1824 16716 PrintWriter pw, String[] args) { 1825 16717 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 1826 16718 if (procs == null) { 1827 16719 pw.println("No process found for: " + args[0]); 1828 16720 return; 1829 16721 } 1830 16722 1831 16723 long uptime = SystemClock.uptimeMillis(); 1832 16724 long realtime = SystemClock.elapsedRealtime(); 1833 16725 pw.println("Applications Graphics Acceleration Info:"); 1834 16726 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 1835 16727 1836 16728 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 1837 16729 ProcessRecord r = procs.get(i); 1838 16730 if (r.thread != null) { 1839 16731 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 1840 16732 pw.flush(); 1841 16733 try { 1842 16734 TransferPipe tp = new TransferPipe(); 1843 16735 try { 1844 16736 r.thread.dumpGfxInfo(tp.getWriteFd(), args); 1845 16737 tp.go(fd); 1846 16738 } finally { 1847 16739 tp.kill(); 1848 16740 } 1849 16741 } catch (IOException e) { 1850 16742 pw.println("Failure while dumping the app: " + r); 1851 16743 pw.flush(); 1852 16744 } catch (RemoteException e) { 1853 16745 pw.println("Got a RemoteException while dumping the app " + r); 1854 16746 pw.flush(); 1855 16747 } 1856 16748 } 1857 16749 } 1858 16750 } 1859 16751 1860 16752 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 1861 16753 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args); 1862 16754 if (procs == null) { 1863 16755 pw.println("No process found for: " + args[0]); 1864 16756 return; 1865 16757 } 1866 16758 1867 16759 pw.println("Applications Database Info:"); 1868 16760 1869 16761 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 1870 16762 ProcessRecord r = procs.get(i); 1871 16763 if (r.thread != null) { 1872 16764 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 1873 16765 pw.flush(); 1874 16766 try { 1875 16767 TransferPipe tp = new TransferPipe(); 1876 16768 try { 1877 16769 r.thread.dumpDbInfo(tp.getWriteFd(), args); 1878 16770 tp.go(fd); 1879 16771 } finally { 1880 16772 tp.kill(); 1881 16773 } 1882 16774 } catch (IOException e) { 1883 16775 pw.println("Failure while dumping the app: " + r); 1884 16776 pw.flush(); 1885 16777 } catch (RemoteException e) { 1886 16778 pw.println("Got a RemoteException while dumping the app " + r); 1887 16779 pw.flush(); 1888 16780 } 1889 16781 } 1890 16782 } 1891 16783 } 1892 16784 1893 16785 final static class MemItem { 1894 16786 final boolean isProc; 1895 16787 final String label; 1896 16788 final String shortLabel; 1897 16789 final long pss; 1898 16790 final long swapPss; 1899 16791 final int id; 1900 16792 final boolean hasActivities; 1901 16793 ArrayList<MemItem> subitems; 1902 16794 1903 16795 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id, 1904 16796 boolean _hasActivities) { 1905 16797 isProc = true; 1906 16798 label = _label; 1907 16799 shortLabel = _shortLabel; 1908 16800 pss = _pss; 1909 16801 swapPss = _swapPss; 1910 16802 id = _id; 1911 16803 hasActivities = _hasActivities; 1912 16804 } 1913 16805 1914 16806 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) { 1915 16807 isProc = false; 1916 16808 label = _label; 1917 16809 shortLabel = _shortLabel; 1918 16810 pss = _pss; 1919 16811 swapPss = _swapPss; 1920 16812 id = _id; 1921 16813 hasActivities = false; 1922 16814 } 1923 16815 } 1924 16816 1925 16817 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 1926 16818 ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) { 1927 16819 if (sort && !isCompact) { 1928 16820 Collections.sort(items, new Comparator<MemItem>() { 1929 16821 @Override 1930 16822 public int compare(MemItem lhs, MemItem rhs) { 1931 16823 if (lhs.pss < rhs.pss) { 1932 16824 return 1; 1933 16825 } else if (lhs.pss > rhs.pss) { 1934 16826 return -1; 1935 16827 } 1936 16828 return 0; 1937 16829 } 1938 16830 }); 1939 16831 } 1940 16832 1941 16833 for (int i=0; i<items.size(); i++) { 1942 16834 MemItem mi = items.get(i); 1943 16835 if (!isCompact) { 1944 16836 if (dumpSwapPss) { 1945 16837 pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss), 1946 16838 mi.label, stringifyKBSize(mi.swapPss)); 1947 16839 } else { 1948 16840 pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label); 1949 16841 } 1950 16842 } else if (mi.isProc) { 1951 16843 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 1952 16844 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(","); 1953 16845 pw.print(dumpSwapPss ? mi.swapPss : "N/A"); 1954 16846 pw.println(mi.hasActivities ? ",a" : ",e"); 1955 16847 } else { 1956 16848 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 1957 16849 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A"); 1958 16850 } 1959 16851 if (mi.subitems != null) { 1960 16852 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 1961 16853 true, isCompact, dumpSwapPss); 1962 16854 } 1963 16855 } 1964 16856 } 1965 16857 1966 16858 // These are in KB. 1967 16859 static final long[] DUMP_MEM_BUCKETS = new long[] { 1968 16860 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 1969 16861 120*1024, 160*1024, 200*1024, 1970 16862 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 1971 16863 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 1972 16864 }; 1973 16865 1974 16866 static final void appendMemBucket(StringBuilder out, long memKB, String label, 1975 16867 boolean stackLike) { 1976 16868 int start = label.lastIndexOf('.'); 1977 16869 if (start >= 0) start++; 1978 16870 else start = 0; 1979 16871 int end = label.length(); 1980 16872 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 1981 16873 if (DUMP_MEM_BUCKETS[i] >= memKB) { 1982 16874 long bucket = DUMP_MEM_BUCKETS[i]/1024; 1983 16875 out.append(bucket); 1984 16876 out.append(stackLike ? "MB." : "MB "); 1985 16877 out.append(label, start, end); 1986 16878 return; 1987 16879 } 1988 16880 } 1989 16881 out.append(memKB/1024); 1990 16882 out.append(stackLike ? "MB." : "MB "); 1991 16883 out.append(label, start, end); 1992 16884 } 1993 16885 1994 16886 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 1995 16887 ProcessList.NATIVE_ADJ, 1996 16888 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, 1997 16889 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ, 1998 16890 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 1999 16891 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 2000 16892 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 2001 16893 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ 2002 16894 }; 2003 16895 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 2004 16896 "Native", 2005 16897 "System", "Persistent", "Persistent Service", "Foreground", 2006 16898 "Visible", "Perceptible", 2007 16899 "Heavy Weight", "Backup", 2008 16900 "A Services", "Home", 2009 16901 "Previous", "B Services", "Cached" 2010 16902 }; 2011 16903 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 2012 16904 "native", 2013 16905 "sys", "pers", "persvc", "fore", 2014 16906 "vis", "percept", 2015 16907 "heavy", "backup", 2016 16908 "servicea", "home", 2017 16909 "prev", "serviceb", "cached" 2018 16910 }; 2019 16911 2020 16912 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 2021 16913 long realtime, boolean isCheckinRequest, boolean isCompact) { 2022 16914 if (isCompact) { 2023 16915 pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION); 2024 16916 } 2025 16917 if (isCheckinRequest || isCompact) { 2026 16918 // short checkin version 2027 16919 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 2028 16920 } else { 2029 16921 pw.println("Applications Memory Usage (in Kilobytes):"); 2030 16922 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 2031 16923 } 2032 16924 } 2033 16925 2034 16926 private static final int KSM_SHARED = 0; 2035 16927 private static final int KSM_SHARING = 1; 2036 16928 private static final int KSM_UNSHARED = 2; 2037 16929 private static final int KSM_VOLATILE = 3; 2038 16930 2039 16931 private final long[] getKsmInfo() { 2040 16932 long[] longOut = new long[4]; 2041 16933 final int[] SINGLE_LONG_FORMAT = new int[] { 2042 16934 PROC_SPACE_TERM| PROC_OUT_LONG 2043 16935 }; 2044 16936 long[] longTmp = new long[1]; 2045 16937 readProcFile("/sys/kernel/mm/ksm/pages_shared", 2046 16938 SINGLE_LONG_FORMAT, null, longTmp, null); 2047 16939 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 2048 16940 longTmp[0] = 0; 2049 16941 readProcFile("/sys/kernel/mm/ksm/pages_sharing", 2050 16942 SINGLE_LONG_FORMAT, null, longTmp, null); 2051 16943 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 2052 16944 longTmp[0] = 0; 2053 16945 readProcFile("/sys/kernel/mm/ksm/pages_unshared", 2054 16946 SINGLE_LONG_FORMAT, null, longTmp, null); 2055 16947 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 2056 16948 longTmp[0] = 0; 2057 16949 readProcFile("/sys/kernel/mm/ksm/pages_volatile", 2058 16950 SINGLE_LONG_FORMAT, null, longTmp, null); 2059 16951 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024; 2060 16952 return longOut; 2061 16953 } 2062 16954 2063 16955 private static String stringifySize(long size, int order) { 2064 16956 Locale locale = Locale.US; 2065 16957 switch (order) { 2066 16958 case 1: 2067 16959 return String.format(locale, "%,13d", size); 2068 16960 case 1024: 2069 16961 return String.format(locale, "%,9dK", size / 1024); 2070 16962 case 1024 * 1024: 2071 16963 return String.format(locale, "%,5dM", size / 1024 / 1024); 2072 16964 case 1024 * 1024 * 1024: 2073 16965 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024); 2074 16966 default: 2075 16967 throw new IllegalArgumentException("Invalid size order"); 2076 16968 } 2077 16969 } 2078 16970 2079 16971 private static String stringifyKBSize(long size) { 2080 16972 return stringifySize(size * 1024, 1024); 2081 16973 } 2082 16974 2083 16975 // Update this version number in case you change the 'compact' format 2084 16976 private static final int MEMINFO_COMPACT_VERSION = 1; 2085 16977 2086 16978 final void dumpApplicationMemoryUsage(FileDescriptor fd, 2087 16979 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 2088 16980 boolean dumpDetails = false; 2089 16981 boolean dumpFullDetails = false; 2090 16982 boolean dumpDalvik = false; 2091 16983 boolean dumpSummaryOnly = false; 2092 16984 boolean dumpUnreachable = false; 2093 16985 boolean oomOnly = false; 2094 16986 boolean isCompact = false; 2095 16987 boolean localOnly = false; 2096 16988 boolean packages = false; 2097 16989 boolean isCheckinRequest = false; 2098 16990 boolean dumpSwapPss = false; 2099 16991 2100 16992 int opti = 0; 2101 16993 while (opti < args.length) { 2102 16994 String opt = args[opti]; 2103 16995 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 2104 16996 break; 2105 16997 } 2106 16998 opti++; 2107 16999 if ("-a".equals(opt)) { 2108 17000 dumpDetails = true; 2109 17001 dumpFullDetails = true; 2110 17002 dumpDalvik = true; 2111 17003 dumpSwapPss = true; 2112 17004 } else if ("-d".equals(opt)) { 2113 17005 dumpDalvik = true; 2114 17006 } else if ("-c".equals(opt)) { 2115 17007 isCompact = true; 2116 17008 } else if ("-s".equals(opt)) { 2117 17009 dumpDetails = true; 2118 17010 dumpSummaryOnly = true; 2119 17011 } else if ("-S".equals(opt)) { 2120 17012 dumpSwapPss = true; 2121 17013 } else if ("--unreachable".equals(opt)) { 2122 17014 dumpUnreachable = true; 2123 17015 } else if ("--oom".equals(opt)) { 2124 17016 oomOnly = true; 2125 17017 } else if ("--local".equals(opt)) { 2126 17018 localOnly = true; 2127 17019 } else if ("--package".equals(opt)) { 2128 17020 packages = true; 2129 17021 } else if ("--checkin".equals(opt)) { 2130 17022 isCheckinRequest = true; 2131 17023 2132 17024 } else if ("-h".equals(opt)) { 2133 17025 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]"); 2134 17026 pw.println(" -a: include all available information for each process."); 2135 17027 pw.println(" -d: include dalvik details."); 2136 17028 pw.println(" -c: dump in a compact machine-parseable representation."); 2137 17029 pw.println(" -s: dump only summary of application memory usage."); 2138 17030 pw.println(" -S: dump also SwapPss."); 2139 17031 pw.println(" --oom: only show processes organized by oom adj."); 2140 17032 pw.println(" --local: only collect details locally, don't call process."); 2141 17033 pw.println(" --package: interpret process arg as package, dumping all"); 2142 17034 pw.println(" processes that have loaded that package."); 2143 17035 pw.println(" --checkin: dump data for a checkin"); 2144 17036 pw.println("If [process] is specified it can be the name or "); 2145 17037 pw.println("pid of a specific process to dump."); 2146 17038 return; 2147 17039 } else { 2148 17040 pw.println("Unknown argument: " + opt + "; use -h for help"); 2149 17041 } 2150 17042 } 2151 17043 2152 17044 long uptime = SystemClock.uptimeMillis(); 2153 17045 long realtime = SystemClock.elapsedRealtime(); 2154 17046 final long[] tmpLong = new long[1]; 2155 17047 2156 17048 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args); 2157 17049 if (procs == null) { 2158 17050 // No Java processes. Maybe they want to print a native process. 2159 17051 if (args != null && args.length > opti 2160 17052 && args[opti].charAt(0) != '-') { 2161 17053 ArrayList<ProcessCpuTracker.Stats> nativeProcs 2162 17054 = new ArrayList<ProcessCpuTracker.Stats>(); 2163 17055 updateCpuStatsNow(); 2164 17056 int findPid = -1; 2165 17057 try { 2166 17058 findPid = Integer.parseInt(args[opti]); 2167 17059 } catch (NumberFormatException e) { 2168 17060 } 2169 17061 synchronized (mProcessCpuTracker) { 2170 17062 final int N = mProcessCpuTracker.countStats(); 2171 17063 for (int i=0; i<N; i++) { 2172 17064 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2173 17065 if (st.pid == findPid || (st.baseName != null 2174 17066 && st.baseName.equals(args[opti]))) { 2175 17067 nativeProcs.add(st); 2176 17068 } 2177 17069 } 2178 17070 } 2179 17071 if (nativeProcs.size() > 0) { 2180 17072 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 2181 17073 isCompact); 2182 17074 Debug.MemoryInfo mi = null; 2183 17075 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 2184 17076 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 2185 17077 final int pid = r.pid; 2186 17078 if (!isCheckinRequest && dumpDetails) { 2187 17079 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 2188 17080 } 2189 17081 if (mi == null) { 2190 17082 mi = new Debug.MemoryInfo(); 2191 17083 } 2192 17084 if (dumpDetails || (!brief && !oomOnly)) { 2193 17085 Debug.getMemoryInfo(pid, mi); 2194 17086 } else { 2195 17087 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null); 2196 17088 mi.dalvikPrivateDirty = (int)tmpLong[0]; 2197 17089 } 2198 17090 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 2199 17091 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0); 2200 17092 if (isCheckinRequest) { 2201 17093 pw.println(); 2202 17094 } 2203 17095 } 2204 17096 return; 2205 17097 } 2206 17098 } 2207 17099 pw.println("No process found for: " + args[opti]); 2208 17100 return; 2209 17101 } 2210 17102 2211 17103 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) { 2212 17104 dumpDetails = true; 2213 17105 } 2214 17106 2215 17107 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 2216 17108 2217 17109 String[] innerArgs = new String[args.length-opti]; 2218 17110 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 2219 17111 2220 17112 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 2221 17113 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 2222 17114 long nativePss = 0; 2223 17115 long nativeSwapPss = 0; 2224 17116 long dalvikPss = 0; 2225 17117 long dalvikSwapPss = 0; 2226 17118 long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] : 2227 17119 EmptyArray.LONG; 2228 17120 long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] : 2229 17121 EmptyArray.LONG; 2230 17122 long otherPss = 0; 2231 17123 long otherSwapPss = 0; 2232 17124 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 2233 17125 long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 2234 17126 2235 17127 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 2236 17128 long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 2237 17129 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 2238 17130 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 2239 17131 2240 17132 long totalPss = 0; 2241 17133 long totalSwapPss = 0; 2242 17134 long cachedPss = 0; 2243 17135 long cachedSwapPss = 0; 2244 17136 boolean hasSwapPss = false; 2245 17137 2246 17138 Debug.MemoryInfo mi = null; 2247 17139 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 2248 17140 final ProcessRecord r = procs.get(i); 2249 17141 final IApplicationThread thread; 2250 17142 final int pid; 2251 17143 final int oomAdj; 2252 17144 final boolean hasActivities; 2253 17145 synchronized (this) { 2254 17146 thread = r.thread; 2255 17147 pid = r.pid; 2256 17148 oomAdj = r.getSetAdjWithServices(); 2257 17149 hasActivities = r.activities.size() > 0; 2258 17150 } 2259 17151 if (thread != null) { 2260 17152 if (!isCheckinRequest && dumpDetails) { 2261 17153 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 2262 17154 } 2263 17155 if (mi == null) { 2264 17156 mi = new Debug.MemoryInfo(); 2265 17157 } 2266 17158 if (dumpDetails || (!brief && !oomOnly)) { 2267 17159 Debug.getMemoryInfo(pid, mi); 2268 17160 hasSwapPss = mi.hasSwappedOutPss; 2269 17161 } else { 2270 17162 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null); 2271 17163 mi.dalvikPrivateDirty = (int)tmpLong[0]; 2272 17164 } 2273 17165 if (dumpDetails) { 2274 17166 if (localOnly) { 2275 17167 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 2276 17168 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0); 2277 17169 if (isCheckinRequest) { 2278 17170 pw.println(); 2279 17171 } 2280 17172 } else { 2281 17173 pw.flush(); 2282 17174 try { 2283 17175 TransferPipe tp = new TransferPipe(); 2284 17176 try { 2285 17177 thread.dumpMemInfo(tp.getWriteFd(), 2286 17178 mi, isCheckinRequest, dumpFullDetails, 2287 17179 dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs); 2288 17180 tp.go(fd); 2289 17181 } finally { 2290 17182 tp.kill(); 2291 17183 } 2292 17184 } catch (IOException e) { 2293 17185 if (!isCheckinRequest) { 2294 17186 pw.println("Got IoException!"); 2295 17187 pw.flush(); 2296 17188 } 2297 17189 } catch (RemoteException e) { 2298 17190 if (!isCheckinRequest) { 2299 17191 pw.println("Got RemoteException!"); 2300 17192 pw.flush(); 2301 17193 } 2302 17194 } 2303 17195 } 2304 17196 } 2305 17197 2306 17198 final long myTotalPss = mi.getTotalPss(); 2307 17199 final long myTotalUss = mi.getTotalUss(); 2308 17200 final long myTotalSwapPss = mi.getTotalSwappedOutPss(); 2309 17201 2310 17202 synchronized (this) { 2311 17203 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 2312 17204 // Record this for posterity if the process has been stable. 2313 17205 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 2314 17206 } 2315 17207 } 2316 17208 2317 17209 if (!isCheckinRequest && mi != null) { 2318 17210 totalPss += myTotalPss; 2319 17211 totalSwapPss += myTotalSwapPss; 2320 17212 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 2321 17213 (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss, 2322 17214 myTotalSwapPss, pid, hasActivities); 2323 17215 procMems.add(pssItem); 2324 17216 procMemsMap.put(pid, pssItem); 2325 17217 2326 17218 nativePss += mi.nativePss; 2327 17219 nativeSwapPss += mi.nativeSwappedOutPss; 2328 17220 dalvikPss += mi.dalvikPss; 2329 17221 dalvikSwapPss += mi.dalvikSwappedOutPss; 2330 17222 for (int j=0; j<dalvikSubitemPss.length; j++) { 2331 17223 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j); 2332 17224 dalvikSubitemSwapPss[j] += 2333 17225 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j); 2334 17226 } 2335 17227 otherPss += mi.otherPss; 2336 17228 otherSwapPss += mi.otherSwappedOutPss; 2337 17229 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 2338 17230 long mem = mi.getOtherPss(j); 2339 17231 miscPss[j] += mem; 2340 17232 otherPss -= mem; 2341 17233 mem = mi.getOtherSwappedOutPss(j); 2342 17234 miscSwapPss[j] += mem; 2343 17235 otherSwapPss -= mem; 2344 17236 } 2345 17237 2346 17238 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 2347 17239 cachedPss += myTotalPss; 2348 17240 cachedSwapPss += myTotalSwapPss; 2349 17241 } 2350 17242 2351 17243 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 2352 17244 if (oomIndex == (oomPss.length - 1) 2353 17245 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex] 2354 17246 && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) { 2355 17247 oomPss[oomIndex] += myTotalPss; 2356 17248 oomSwapPss[oomIndex] += myTotalSwapPss; 2357 17249 if (oomProcs[oomIndex] == null) { 2358 17250 oomProcs[oomIndex] = new ArrayList<MemItem>(); 2359 17251 } 2360 17252 oomProcs[oomIndex].add(pssItem); 2361 17253 break; 2362 17254 } 2363 17255 } 2364 17256 } 2365 17257 } 2366 17258 } 2367 17259 2368 17260 long nativeProcTotalPss = 0; 2369 17261 2370 17262 if (!isCheckinRequest && procs.size() > 1 && !packages) { 2371 17263 // If we are showing aggregations, also look for native processes to 2372 17264 // include so that our aggregations are more accurate. 2373 17265 updateCpuStatsNow(); 2374 17266 mi = null; 2375 17267 synchronized (mProcessCpuTracker) { 2376 17268 final int N = mProcessCpuTracker.countStats(); 2377 17269 for (int i=0; i<N; i++) { 2378 17270 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2379 17271 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 2380 17272 if (mi == null) { 2381 17273 mi = new Debug.MemoryInfo(); 2382 17274 } 2383 17275 if (!brief && !oomOnly) { 2384 17276 Debug.getMemoryInfo(st.pid, mi); 2385 17277 } else { 2386 17278 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null); 2387 17279 mi.nativePrivateDirty = (int)tmpLong[0]; 2388 17280 } 2389 17281 2390 17282 final long myTotalPss = mi.getTotalPss(); 2391 17283 final long myTotalSwapPss = mi.getTotalSwappedOutPss(); 2392 17284 totalPss += myTotalPss; 2393 17285 nativeProcTotalPss += myTotalPss; 2394 17286 2395 17287 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 2396 17288 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false); 2397 17289 procMems.add(pssItem); 2398 17290 2399 17291 nativePss += mi.nativePss; 2400 17292 nativeSwapPss += mi.nativeSwappedOutPss; 2401 17293 dalvikPss += mi.dalvikPss; 2402 17294 dalvikSwapPss += mi.dalvikSwappedOutPss; 2403 17295 for (int j=0; j<dalvikSubitemPss.length; j++) { 2404 17296 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j); 2405 17297 dalvikSubitemSwapPss[j] += 2406 17298 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j); 2407 17299 } 2408 17300 otherPss += mi.otherPss; 2409 17301 otherSwapPss += mi.otherSwappedOutPss; 2410 17302 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 2411 17303 long mem = mi.getOtherPss(j); 2412 17304 miscPss[j] += mem; 2413 17305 otherPss -= mem; 2414 17306 mem = mi.getOtherSwappedOutPss(j); 2415 17307 miscSwapPss[j] += mem; 2416 17308 otherSwapPss -= mem; 2417 17309 } 2418 17310 oomPss[0] += myTotalPss; 2419 17311 oomSwapPss[0] += myTotalSwapPss; 2420 17312 if (oomProcs[0] == null) { 2421 17313 oomProcs[0] = new ArrayList<MemItem>(); 2422 17314 } 2423 17315 oomProcs[0].add(pssItem); 2424 17316 } 2425 17317 } 2426 17318 } 2427 17319 2428 17320 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 2429 17321 2430 17322 catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1)); 2431 17323 final MemItem dalvikItem = 2432 17324 new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2); 2433 17325 if (dalvikSubitemPss.length > 0) { 2434 17326 dalvikItem.subitems = new ArrayList<MemItem>(); 2435 17327 for (int j=0; j<dalvikSubitemPss.length; j++) { 2436 17328 final String name = Debug.MemoryInfo.getOtherLabel( 2437 17329 Debug.MemoryInfo.NUM_OTHER_STATS + j); 2438 17330 dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j], 2439 17331 dalvikSubitemSwapPss[j], j)); 2440 17332 } 2441 17333 } 2442 17334 catMems.add(dalvikItem); 2443 17335 catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3)); 2444 17336 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 2445 17337 String label = Debug.MemoryInfo.getOtherLabel(j); 2446 17338 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j)); 2447 17339 } 2448 17340 2449 17341 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 2450 17342 for (int j=0; j<oomPss.length; j++) { 2451 17343 if (oomPss[j] != 0) { 2452 17344 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 2453 17345 : DUMP_MEM_OOM_LABEL[j]; 2454 17346 MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j], 2455 17347 DUMP_MEM_OOM_ADJ[j]); 2456 17348 item.subitems = oomProcs[j]; 2457 17349 oomMems.add(item); 2458 17350 } 2459 17351 } 2460 17352 2461 17353 dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0; 2462 17354 if (!brief && !oomOnly && !isCompact) { 2463 17355 pw.println(); 2464 17356 pw.println("Total PSS by process:"); 2465 17357 dumpMemItems(pw, " ", "proc", procMems, true, isCompact, dumpSwapPss); 2466 17358 pw.println(); 2467 17359 } 2468 17360 if (!isCompact) { 2469 17361 pw.println("Total PSS by OOM adjustment:"); 2470 17362 } 2471 17363 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact, dumpSwapPss); 2472 17364 if (!brief && !oomOnly) { 2473 17365 PrintWriter out = categoryPw != null ? categoryPw : pw; 2474 17366 if (!isCompact) { 2475 17367 out.println(); 2476 17368 out.println("Total PSS by category:"); 2477 17369 } 2478 17370 dumpMemItems(out, " ", "cat", catMems, true, isCompact, dumpSwapPss); 2479 17371 } 2480 17372 if (!isCompact) { 2481 17373 pw.println(); 2482 17374 } 2483 17375 MemInfoReader memInfo = new MemInfoReader(); 2484 17376 memInfo.readMemInfo(); 2485 17377 if (nativeProcTotalPss > 0) { 2486 17378 synchronized (this) { 2487 17379 final long cachedKb = memInfo.getCachedSizeKb(); 2488 17380 final long freeKb = memInfo.getFreeSizeKb(); 2489 17381 final long zramKb = memInfo.getZramTotalSizeKb(); 2490 17382 final long kernelKb = memInfo.getKernelUsedSizeKb(); 2491 17383 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024, 2492 17384 kernelKb*1024, nativeProcTotalPss*1024); 2493 17385 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb, 2494 17386 nativeProcTotalPss); 2495 17387 } 2496 17388 } 2497 17389 if (!brief) { 2498 17390 if (!isCompact) { 2499 17391 pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb())); 2500 17392 pw.print(" (status "); 2501 17393 switch (mLastMemoryLevel) { 2502 17394 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 2503 17395 pw.println("normal)"); 2504 17396 break; 2505 17397 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 2506 17398 pw.println("moderate)"); 2507 17399 break; 2508 17400 case ProcessStats.ADJ_MEM_FACTOR_LOW: 2509 17401 pw.println("low)"); 2510 17402 break; 2511 17403 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 2512 17404 pw.println("critical)"); 2513 17405 break; 2514 17406 default: 2515 17407 pw.print(mLastMemoryLevel); 2516 17408 pw.println(")"); 2517 17409 break; 2518 17410 } 2519 17411 pw.print(" Free RAM: "); 2520 17412 pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb() 2521 17413 + memInfo.getFreeSizeKb())); 2522 17414 pw.print(" ("); 2523 17415 pw.print(stringifyKBSize(cachedPss)); 2524 17416 pw.print(" cached pss + "); 2525 17417 pw.print(stringifyKBSize(memInfo.getCachedSizeKb())); 2526 17418 pw.print(" cached kernel + "); 2527 17419 pw.print(stringifyKBSize(memInfo.getFreeSizeKb())); 2528 17420 pw.println(" free)"); 2529 17421 } else { 2530 17422 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 2531 17423 pw.print(cachedPss + memInfo.getCachedSizeKb() 2532 17424 + memInfo.getFreeSizeKb()); pw.print(","); 2533 17425 pw.println(totalPss - cachedPss); 2534 17426 } 2535 17427 } 2536 17428 long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss) 2537 17429 - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 2538 17430 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb(); 2539 17431 if (!isCompact) { 2540 17432 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss 2541 17433 + memInfo.getKernelUsedSizeKb())); pw.print(" ("); 2542 17434 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + "); 2543 17435 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n"); 2544 17436 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM)); 2545 17437 } else { 2546 17438 pw.print("lostram,"); pw.println(lostRAM); 2547 17439 } 2548 17440 if (!brief) { 2549 17441 if (memInfo.getZramTotalSizeKb() != 0) { 2550 17442 if (!isCompact) { 2551 17443 pw.print(" ZRAM: "); 2552 17444 pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb())); 2553 17445 pw.print(" physical used for "); 2554 17446 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb() 2555 17447 - memInfo.getSwapFreeSizeKb())); 2556 17448 pw.print(" in swap ("); 2557 17449 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb())); 2558 17450 pw.println(" total swap)"); 2559 17451 } else { 2560 17452 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 2561 17453 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 2562 17454 pw.println(memInfo.getSwapFreeSizeKb()); 2563 17455 } 2564 17456 } 2565 17457 final long[] ksm = getKsmInfo(); 2566 17458 if (!isCompact) { 2567 17459 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 2568 17460 || ksm[KSM_VOLATILE] != 0) { 2569 17461 pw.print(" KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING])); 2570 17462 pw.print(" saved from shared "); 2571 17463 pw.print(stringifyKBSize(ksm[KSM_SHARED])); 2572 17464 pw.print(" "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED])); 2573 17465 pw.print(" unshared; "); 2574 17466 pw.print(stringifyKBSize( 2575 17467 ksm[KSM_VOLATILE])); pw.println(" volatile"); 2576 17468 } 2577 17469 pw.print(" Tuning: "); 2578 17470 pw.print(ActivityManager.staticGetMemoryClass()); 2579 17471 pw.print(" (large "); 2580 17472 pw.print(ActivityManager.staticGetLargeMemoryClass()); 2581 17473 pw.print("), oom "); 2582 17474 pw.print(stringifySize( 2583 17475 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024)); 2584 17476 pw.print(", restore limit "); 2585 17477 pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb())); 2586 17478 if (ActivityManager.isLowRamDeviceStatic()) { 2587 17479 pw.print(" (low-ram)"); 2588 17480 } 2589 17481 if (ActivityManager.isHighEndGfx()) { 2590 17482 pw.print(" (high-end-gfx)"); 2591 17483 } 2592 17484 pw.println(); 2593 17485 } else { 2594 17486 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(","); 2595 17487 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]); 2596 17488 pw.print(","); pw.println(ksm[KSM_VOLATILE]); 2597 17489 pw.print("tuning,"); 2598 17490 pw.print(ActivityManager.staticGetMemoryClass()); 2599 17491 pw.print(','); 2600 17492 pw.print(ActivityManager.staticGetLargeMemoryClass()); 2601 17493 pw.print(','); 2602 17494 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 2603 17495 if (ActivityManager.isLowRamDeviceStatic()) { 2604 17496 pw.print(",low-ram"); 2605 17497 } 2606 17498 if (ActivityManager.isHighEndGfx()) { 2607 17499 pw.print(",high-end-gfx"); 2608 17500 } 2609 17501 pw.println(); 2610 17502 } 2611 17503 } 2612 17504 } 2613 17505 } 2614 17506 2615 17507 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss, 2616 17508 long memtrack, String name) { 2617 17509 sb.append(" "); 2618 17510 sb.append(ProcessList.makeOomAdjString(oomAdj)); 2619 17511 sb.append(' '); 2620 17512 sb.append(ProcessList.makeProcStateString(procState)); 2621 17513 sb.append(' '); 2622 17514 ProcessList.appendRamKb(sb, pss); 2623 17515 sb.append(": "); 2624 17516 sb.append(name); 2625 17517 if (memtrack > 0) { 2626 17518 sb.append(" ("); 2627 17519 sb.append(stringifyKBSize(memtrack)); 2628 17520 sb.append(" memtrack)"); 2629 17521 } 2630 17522 } 2631 17523 2632 17524 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) { 2633 17525 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name); 2634 17526 sb.append(" (pid "); 2635 17527 sb.append(mi.pid); 2636 17528 sb.append(") "); 2637 17529 sb.append(mi.adjType); 2638 17530 sb.append('\n'); 2639 17531 if (mi.adjReason != null) { 2640 17532 sb.append(" "); 2641 17533 sb.append(mi.adjReason); 2642 17534 sb.append('\n'); 2643 17535 } 2644 17536 } 2645 17537 2646 17538 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) { 2647 17539 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size()); 2648 17540 for (int i=0, N=memInfos.size(); i<N; i++) { 2649 17541 ProcessMemInfo mi = memInfos.get(i); 2650 17542 infoMap.put(mi.pid, mi); 2651 17543 } 2652 17544 updateCpuStatsNow(); 2653 17545 long[] memtrackTmp = new long[1]; 2654 17546 final List<ProcessCpuTracker.Stats> stats; 2655 17547 // Get a list of Stats that have vsize > 0 2656 17548 synchronized (mProcessCpuTracker) { 2657 17549 stats = mProcessCpuTracker.getStats((st) -> { 2658 17550 return st.vsize > 0; 2659 17551 }); 2660 17552 } 2661 17553 final int statsCount = stats.size(); 2662 17554 for (int i = 0; i < statsCount; i++) { 2663 17555 ProcessCpuTracker.Stats st = stats.get(i); 2664 17556 long pss = Debug.getPss(st.pid, null, memtrackTmp); 2665 17557 if (pss > 0) { 2666 17558 if (infoMap.indexOfKey(st.pid) < 0) { 2667 17559 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 2668 17560 ProcessList.NATIVE_ADJ, -1, "native", null); 2669 17561 mi.pss = pss; 2670 17562 mi.memtrack = memtrackTmp[0]; 2671 17563 memInfos.add(mi); 2672 17564 } 2673 17565 } 2674 17566 } 2675 17567 2676 17568 long totalPss = 0; 2677 17569 long totalMemtrack = 0; 2678 17570 for (int i=0, N=memInfos.size(); i<N; i++) { 2679 17571 ProcessMemInfo mi = memInfos.get(i); 2680 17572 if (mi.pss == 0) { 2681 17573 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp); 2682 17574 mi.memtrack = memtrackTmp[0]; 2683 17575 } 2684 17576 totalPss += mi.pss; 2685 17577 totalMemtrack += mi.memtrack; 2686 17578 } 2687 17579 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 2688 17580 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 2689 17581 if (lhs.oomAdj != rhs.oomAdj) { 2690 17582 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 2691 17583 } 2692 17584 if (lhs.pss != rhs.pss) { 2693 17585 return lhs.pss < rhs.pss ? 1 : -1; 2694 17586 } 2695 17587 return 0; 2696 17588 } 2697 17589 }); 2698 17590 2699 17591 StringBuilder tag = new StringBuilder(128); 2700 17592 StringBuilder stack = new StringBuilder(128); 2701 17593 tag.append("Low on memory -- "); 2702 17594 appendMemBucket(tag, totalPss, "total", false); 2703 17595 appendMemBucket(stack, totalPss, "total", true); 2704 17596 2705 17597 StringBuilder fullNativeBuilder = new StringBuilder(1024); 2706 17598 StringBuilder shortNativeBuilder = new StringBuilder(1024); 2707 17599 StringBuilder fullJavaBuilder = new StringBuilder(1024); 2708 17600 2709 17601 boolean firstLine = true; 2710 17602 int lastOomAdj = Integer.MIN_VALUE; 2711 17603 long extraNativeRam = 0; 2712 17604 long extraNativeMemtrack = 0; 2713 17605 long cachedPss = 0; 2714 17606 for (int i=0, N=memInfos.size(); i<N; i++) { 2715 17607 ProcessMemInfo mi = memInfos.get(i); 2716 17608 2717 17609 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 2718 17610 cachedPss += mi.pss; 2719 17611 } 2720 17612 2721 17613 if (mi.oomAdj != ProcessList.NATIVE_ADJ 2722 17614 && (mi.oomAdj < ProcessList.SERVICE_ADJ 2723 17615 || mi.oomAdj == ProcessList.HOME_APP_ADJ 2724 17616 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 2725 17617 if (lastOomAdj != mi.oomAdj) { 2726 17618 lastOomAdj = mi.oomAdj; 2727 17619 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 2728 17620 tag.append(" / "); 2729 17621 } 2730 17622 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 2731 17623 if (firstLine) { 2732 17624 stack.append(":"); 2733 17625 firstLine = false; 2734 17626 } 2735 17627 stack.append("\n\t at "); 2736 17628 } else { 2737 17629 stack.append("$"); 2738 17630 } 2739 17631 } else { 2740 17632 tag.append(" "); 2741 17633 stack.append("$"); 2742 17634 } 2743 17635 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 2744 17636 appendMemBucket(tag, mi.pss, mi.name, false); 2745 17637 } 2746 17638 appendMemBucket(stack, mi.pss, mi.name, true); 2747 17639 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 2748 17640 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 2749 17641 stack.append("("); 2750 17642 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 2751 17643 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 2752 17644 stack.append(DUMP_MEM_OOM_LABEL[k]); 2753 17645 stack.append(":"); 2754 17646 stack.append(DUMP_MEM_OOM_ADJ[k]); 2755 17647 } 2756 17648 } 2757 17649 stack.append(")"); 2758 17650 } 2759 17651 } 2760 17652 2761 17653 appendMemInfo(fullNativeBuilder, mi); 2762 17654 if (mi.oomAdj == ProcessList.NATIVE_ADJ) { 2763 17655 // The short form only has native processes that are >= 512K. 2764 17656 if (mi.pss >= 512) { 2765 17657 appendMemInfo(shortNativeBuilder, mi); 2766 17658 } else { 2767 17659 extraNativeRam += mi.pss; 2768 17660 extraNativeMemtrack += mi.memtrack; 2769 17661 } 2770 17662 } else { 2771 17663 // Short form has all other details, but if we have collected RAM 2772 17664 // from smaller native processes let's dump a summary of that. 2773 17665 if (extraNativeRam > 0) { 2774 17666 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ, 2775 17667 -1, extraNativeRam, extraNativeMemtrack, "(Other native)"); 2776 17668 shortNativeBuilder.append('\n'); 2777 17669 extraNativeRam = 0; 2778 17670 } 2779 17671 appendMemInfo(fullJavaBuilder, mi); 2780 17672 } 2781 17673 } 2782 17674 2783 17675 fullJavaBuilder.append(" "); 2784 17676 ProcessList.appendRamKb(fullJavaBuilder, totalPss); 2785 17677 fullJavaBuilder.append(": TOTAL"); 2786 17678 if (totalMemtrack > 0) { 2787 17679 fullJavaBuilder.append(" ("); 2788 17680 fullJavaBuilder.append(stringifyKBSize(totalMemtrack)); 2789 17681 fullJavaBuilder.append(" memtrack)"); 2790 17682 } else { 2791 17683 } 2792 17684 fullJavaBuilder.append("\n"); 2793 17685 2794 17686 MemInfoReader memInfo = new MemInfoReader(); 2795 17687 memInfo.readMemInfo(); 2796 17688 final long[] infos = memInfo.getRawInfo(); 2797 17689 2798 17690 StringBuilder memInfoBuilder = new StringBuilder(1024); 2799 17691 Debug.getMemInfo(infos); 2800 17692 memInfoBuilder.append(" MemInfo: "); 2801 17693 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, "); 2802 17694 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, "); 2803 17695 memInfoBuilder.append(stringifyKBSize( 2804 17696 infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, "); 2805 17697 memInfoBuilder.append(stringifyKBSize( 2806 17698 infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables "); 2807 17699 memInfoBuilder.append(stringifyKBSize( 2808 17700 infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n"); 2809 17701 memInfoBuilder.append(" "); 2810 17702 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, "); 2811 17703 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, "); 2812 17704 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, "); 2813 17705 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n"); 2814 17706 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 2815 17707 memInfoBuilder.append(" ZRAM: "); 2816 17708 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL])); 2817 17709 memInfoBuilder.append(" RAM, "); 2818 17710 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL])); 2819 17711 memInfoBuilder.append(" swap total, "); 2820 17712 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE])); 2821 17713 memInfoBuilder.append(" swap free\n"); 2822 17714 } 2823 17715 final long[] ksm = getKsmInfo(); 2824 17716 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0 2825 17717 || ksm[KSM_VOLATILE] != 0) { 2826 17718 memInfoBuilder.append(" KSM: "); 2827 17719 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING])); 2828 17720 memInfoBuilder.append(" saved from shared "); 2829 17721 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED])); 2830 17722 memInfoBuilder.append("\n "); 2831 17723 memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED])); 2832 17724 memInfoBuilder.append(" unshared; "); 2833 17725 memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE])); 2834 17726 memInfoBuilder.append(" volatile\n"); 2835 17727 } 2836 17728 memInfoBuilder.append(" Free RAM: "); 2837 17729 memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb() 2838 17730 + memInfo.getFreeSizeKb())); 2839 17731 memInfoBuilder.append("\n"); 2840 17732 memInfoBuilder.append(" Used RAM: "); 2841 17733 memInfoBuilder.append(stringifyKBSize( 2842 17734 totalPss - cachedPss + memInfo.getKernelUsedSizeKb())); 2843 17735 memInfoBuilder.append("\n"); 2844 17736 memInfoBuilder.append(" Lost RAM: "); 2845 17737 memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb() 2846 17738 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 2847 17739 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb())); 2848 17740 memInfoBuilder.append("\n"); 2849 17741 Slog.i(TAG, "Low on memory:"); 2850 17742 Slog.i(TAG, shortNativeBuilder.toString()); 2851 17743 Slog.i(TAG, fullJavaBuilder.toString()); 2852 17744 Slog.i(TAG, memInfoBuilder.toString()); 2853 17745 2854 17746 StringBuilder dropBuilder = new StringBuilder(1024); 2855 17747 /* 2856 17748 StringWriter oomSw = new StringWriter(); 2857 17749 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 2858 17750 StringWriter catSw = new StringWriter(); 2859 17751 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 2860 17752 String[] emptyArgs = new String[] { }; 2861 17753 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 2862 17754 oomPw.flush(); 2863 17755 String oomString = oomSw.toString(); 2864 17756 */ 2865 17757 dropBuilder.append("Low on memory:"); 2866 17758 dropBuilder.append(stack); 2867 17759 dropBuilder.append('\n'); 2868 17760 dropBuilder.append(fullNativeBuilder); 2869 17761 dropBuilder.append(fullJavaBuilder); 2870 17762 dropBuilder.append('\n'); 2871 17763 dropBuilder.append(memInfoBuilder); 2872 17764 dropBuilder.append('\n'); 2873 17765 /* 2874 17766 dropBuilder.append(oomString); 2875 17767 dropBuilder.append('\n'); 2876 17768 */ 2877 17769 StringWriter catSw = new StringWriter(); 2878 17770 synchronized (ActivityManagerService.this) { 2879 17771 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 2880 17772 String[] emptyArgs = new String[] { }; 2881 17773 catPw.println(); 2882 17774 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 2883 17775 catPw.println(); 2884 17776 mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0, 2885 17777 false, null).dumpLocked(); 2886 17778 catPw.println(); 2887 17779 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 2888 17780 catPw.flush(); 2889 17781 } 2890 17782 dropBuilder.append(catSw.toString()); 2891 17783 addErrorToDropBox("lowmem", null, "system_server", null, 2892 17784 null, tag.toString(), dropBuilder.toString(), null, null); 2893 17785 //Slog.i(TAG, "Sent to dropbox:"); 2894 17786 //Slog.i(TAG, dropBuilder.toString()); 2895 17787 synchronized (ActivityManagerService.this) { 2896 17788 long now = SystemClock.uptimeMillis(); 2897 17789 if (mLastMemUsageReportTime < now) { 2898 17790 mLastMemUsageReportTime = now; 2899 17791 } 2900 17792 } 2901 17793 }
扫描args
1 17795 /** 2 17796 * Searches array of arguments for the specified string 3 17797 * @param args array of argument strings 4 17798 * @param value value to search for 5 17799 * @return true if the value is contained in the array 6 17800 */ 7 17801 private static boolean scanArgs(String[] args, String value) { 8 17802 if (args != null) { 9 17803 for (String arg : args) { 10 17804 if (value.equals(arg)) { 11 17805 return true; 12 17806 } 13 17807 } 14 17808 } 15 17809 return false; 16 17810 }
移除正在死亡的provider
1 17812 private final boolean removeDyingProviderLocked(ProcessRecord proc, 2 17813 ContentProviderRecord cpr, boolean always) { 3 17814 final boolean inLaunching = mLaunchingProviders.contains(cpr); 4 17815 5 17816 if (!inLaunching || always) { 6 17817 synchronized (cpr) { 7 17818 cpr.launchingApp = null; 8 17819 cpr.notifyAll(); 9 17820 } 10 17821 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 11 17822 String names[] = cpr.info.authority.split(";"); 12 17823 for (int j = 0; j < names.length; j++) { 13 17824 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14 17825 } 15 17826 } 16 17827 17 17828 for (int i = cpr.connections.size() - 1; i >= 0; i--) { 18 17829 ContentProviderConnection conn = cpr.connections.get(i); 19 17830 if (conn.waiting) { 20 17831 // If this connection is waiting for the provider, then we don't 21 17832 // need to mess with its process unless we are always removing 22 17833 // or for some reason the provider is not currently launching. 23 17834 if (inLaunching && !always) { 24 17835 continue; 25 17836 } 26 17837 } 27 17838 ProcessRecord capp = conn.client; 28 17839 conn.dead = true; 29 17840 if (conn.stableCount > 0) { 30 17841 if (!capp.persistent && capp.thread != null 31 17842 && capp.pid != 0 32 17843 && capp.pid != MY_PID) { 33 17844 capp.kill("depends on provider " 34 17845 + cpr.name.flattenToShortString() 35 17846 + " in dying proc " + (proc != null ? proc.processName : "??") 36 17847 + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true); 37 17848 } 38 17849 } else if (capp.thread != null && conn.provider.provider != null) { 39 17850 try { 40 17851 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 41 17852 } catch (RemoteException e) { 42 17853 } 43 17854 // In the protocol here, we don't expect the client to correctly 44 17855 // clean up this connection, we'll just remove it. 45 17856 cpr.connections.remove(i); 46 17857 if (conn.client.conProviders.remove(conn)) { 47 17858 stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name); 48 17859 } 49 17860 } 50 17861 } 51 17862 52 17863 if (inLaunching && always) { 53 17864 mLaunchingProviders.remove(cpr); 54 17865 } 55 17866 return inLaunching; 56 17867 }
清除应用程序记录
1 17869 /** 2 17870 * Main code for cleaning up a process when it has gone away. This is 3 17871 * called both as a result of the process dying, or directly when stopping 4 17872 * a process when running in single process mode. 5 17873 * 6 17874 * @return Returns true if the given process has been restarted, so the 7 17875 * app that was passed in must remain on the process lists. 8 17876 */ 9 17877 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app, 10 17878 boolean restarting, boolean allowRestart, int index, boolean replacingPid) { 11 17879 if (index >= 0) { 12 17880 removeLruProcessLocked(app); 13 17881 ProcessList.remove(app.pid); 14 17882 } 15 17883 16 17884 mProcessesToGc.remove(app); 17 17885 mPendingPssProcesses.remove(app); 18 17886 19 17887 // Dismiss any open dialogs. 20 17888 if (app.crashDialog != null && !app.forceCrashReport) { 21 17889 app.crashDialog.dismiss(); 22 17890 app.crashDialog = null; 23 17891 } 24 17892 if (app.anrDialog != null) { 25 17893 app.anrDialog.dismiss(); 26 17894 app.anrDialog = null; 27 17895 } 28 17896 if (app.waitDialog != null) { 29 17897 app.waitDialog.dismiss(); 30 17898 app.waitDialog = null; 31 17899 } 32 17900 33 17901 app.crashing = false; 34 17902 app.notResponding = false; 35 17903 36 17904 app.resetPackageList(mProcessStats); 37 17905 app.unlinkDeathRecipient(); 38 17906 app.makeInactive(mProcessStats); 39 17907 app.waitingToKill = null; 40 17908 app.forcingToImportant = null; 41 17909 updateProcessForegroundLocked(app, false, false); 42 17910 app.foregroundActivities = false; 43 17911 app.hasShownUi = false; 44 17912 app.treatLikeActivity = false; 45 17913 app.hasAboveClient = false; 46 17914 app.hasClientActivities = false; 47 17915 48 17916 mServices.killServicesLocked(app, allowRestart); 49 17917 50 17918 boolean restart = false; 51 17919 52 17920 // Remove published content providers. 53 17921 for (int i = app.pubProviders.size() - 1; i >= 0; i--) { 54 17922 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 55 17923 final boolean always = app.bad || !allowRestart; 56 17924 boolean inLaunching = removeDyingProviderLocked(app, cpr, always); 57 17925 if ((inLaunching || always) && cpr.hasConnectionOrHandle()) { 58 17926 // We left the provider in the launching list, need to 59 17927 // restart it. 60 17928 restart = true; 61 17929 } 62 17930 63 17931 cpr.provider = null; 64 17932 cpr.proc = null; 65 17933 } 66 17934 app.pubProviders.clear(); 67 17935 68 17936 // Take care of any launching providers waiting for this process. 69 17937 if (cleanupAppInLaunchingProvidersLocked(app, false)) { 70 17938 restart = true; 71 17939 } 72 17940 73 17941 // Unregister from connected content providers. 74 17942 if (!app.conProviders.isEmpty()) { 75 17943 for (int i = app.conProviders.size() - 1; i >= 0; i--) { 76 17944 ContentProviderConnection conn = app.conProviders.get(i); 77 17945 conn.provider.connections.remove(conn); 78 17946 stopAssociationLocked(app.uid, app.processName, conn.provider.uid, 79 17947 conn.provider.name); 80 17948 } 81 17949 app.conProviders.clear(); 82 17950 } 83 17951 84 17952 // At this point there may be remaining entries in mLaunchingProviders 85 17953 // where we were the only one waiting, so they are no longer of use. 86 17954 // Look for these and clean up if found. 87 17955 // XXX Commented out for now. Trying to figure out a way to reproduce 88 17956 // the actual situation to identify what is actually going on. 89 17957 if (false) { 90 17958 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) { 91 17959 ContentProviderRecord cpr = mLaunchingProviders.get(i); 92 17960 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 93 17961 synchronized (cpr) { 94 17962 cpr.launchingApp = null; 95 17963 cpr.notifyAll(); 96 17964 } 97 17965 } 98 17966 } 99 17967 } 100 17968 101 17969 skipCurrentReceiverLocked(app); 102 17970 103 17971 // Unregister any receivers. 104 17972 for (int i = app.receivers.size() - 1; i >= 0; i--) { 105 17973 removeReceiverLocked(app.receivers.valueAt(i)); 106 17974 } 107 17975 app.receivers.clear(); 108 17976 109 17977 // If the app is undergoing backup, tell the backup manager about it 110 17978 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 111 17979 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App " 112 17980 + mBackupTarget.appInfo + " died during backup"); 113 17981 mHandler.post(new Runnable() { 114 17982 @Override 115 17983 public void run(){ 116 17984 try { 117 17985 IBackupManager bm = IBackupManager.Stub.asInterface( 118 17986 ServiceManager.getService(Context.BACKUP_SERVICE)); 119 17987 bm.agentDisconnected(app.info.packageName); 120 17988 } catch (RemoteException e) { 121 17989 // can't happen; backup manager is local 122 17990 } 123 17991 } 124 17992 }); 125 17993 } 126 17994 127 17995 for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) { 128 17996 ProcessChangeItem item = mPendingProcessChanges.get(i); 129 17997 if (item.pid == app.pid) { 130 17998 mPendingProcessChanges.remove(i); 131 17999 mAvailProcessChanges.add(item); 132 18000 } 133 18001 } 134 18002 mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid, 135 18003 null).sendToTarget(); 136 18004 137 18005 // If the caller is restarting this app, then leave it in its 138 18006 // current lists and let the caller take care of it. 139 18007 if (restarting) { 140 18008 return false; 141 18009 } 142 18010 143 18011 if (!app.persistent || app.isolated) { 144 18012 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP, 145 18013 "Removing non-persistent process during cleanup: " + app); 146 18014 if (!replacingPid) { 147 18015 removeProcessNameLocked(app.processName, app.uid, app); 148 18016 } 149 18017 if (mHeavyWeightProcess == app) { 150 18018 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 151 18019 mHeavyWeightProcess.userId, 0)); 152 18020 mHeavyWeightProcess = null; 153 18021 } 154 18022 } else if (!app.removed) { 155 18023 // This app is persistent, so we need to keep its record around. 156 18024 // If it is not already on the pending app list, add it there 157 18025 // and start a new process for it. 158 18026 if (mPersistentStartingProcesses.indexOf(app) < 0) { 159 18027 mPersistentStartingProcesses.add(app); 160 18028 restart = true; 161 18029 } 162 18030 } 163 18031 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v( 164 18032 TAG_CLEANUP, "Clean-up removing on hold: " + app); 165 18033 mProcessesOnHold.remove(app); 166 18034 167 18035 if (app == mHomeProcess) { 168 18036 mHomeProcess = null; 169 18037 } 170 18038 if (app == mPreviousProcess) { 171 18039 mPreviousProcess = null; 172 18040 } 173 18041 174 18042 if (restart && !app.isolated) { 175 18043 // We have components that still need to be running in the 176 18044 // process, so re-launch it. 177 18045 if (index < 0) { 178 18046 ProcessList.remove(app.pid); 179 18047 } 180 18048 addProcessNameLocked(app); 181 18049 startProcessLocked(app, "restart", app.processName); 182 18050 return true; 183 18051 } else if (app.pid > 0 && app.pid != MY_PID) { 184 18052 // Goodbye! 185 18053 boolean removed; 186 18054 synchronized (mPidsSelfLocked) { 187 18055 mPidsSelfLocked.remove(app.pid); 188 18056 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 189 18057 } 190 18058 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 191 18059 if (app.isolated) { 192 18060 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 193 18061 } 194 18062 app.setPid(0); 195 18063 } 196 18064 return false; 197 18065 }
检查与清除app启动时的provider
1 18067 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) { 2 18068 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) { 3 18069 ContentProviderRecord cpr = mLaunchingProviders.get(i); 4 18070 if (cpr.launchingApp == app) { 5 18071 return true; 6 18072 } 7 18073 } 8 18074 return false; 9 18075 } 10 18076 11 18077 boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12 18078 // Look through the content providers we are waiting to have launched, 13 18079 // and if any run in this process then either schedule a restart of 14 18080 // the process or kill the client waiting for it if this process has 15 18081 // gone bad. 16 18082 boolean restart = false; 17 18083 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) { 18 18084 ContentProviderRecord cpr = mLaunchingProviders.get(i); 19 18085 if (cpr.launchingApp == app) { 20 18086 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) { 21 18087 restart = true; 22 18088 } else { 23 18089 removeDyingProviderLocked(app, cpr, true); 24 18090 } 25 18091 } 26 18092 } 27 18093 return restart; 28 18094 }
service相关
1 18095 2 18096 // ========================================================= 3 18097 // SERVICES 4 18098 // ========================================================= 5 18099 6 18100 @Override 7 18101 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 8 18102 int flags) { 9 18103 enforceNotIsolatedCaller("getServices"); 10 18104 11 18105 final int callingUid = Binder.getCallingUid(); 12 18106 final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission( 13 18107 INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED); 14 18108 final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(), 15 18109 callingUid); 16 18110 synchronized (this) { 17 18111 return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid, 18 18112 allowed, canInteractAcrossUsers); 19 18113 } 20 18114 } 21 18115 22 18116 @Override 23 18117 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 24 18118 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 25 18119 synchronized (this) { 26 18120 return mServices.getRunningServiceControlPanelLocked(name); 27 18121 } 28 18122 } 29 18123 30 18124 @Override 31 18125 public ComponentName startService(IApplicationThread caller, Intent service, 32 18126 String resolvedType, boolean requireForeground, String callingPackage, int userId) 33 18127 throws TransactionTooLargeException { 34 18128 enforceNotIsolatedCaller("startService"); 35 18129 // Refuse possible leaked file descriptors 36 18130 if (service != null && service.hasFileDescriptors() == true) { 37 18131 throw new IllegalArgumentException("File descriptors passed in Intent"); 38 18132 } 39 18133 40 18134 if (callingPackage == null) { 41 18135 throw new IllegalArgumentException("callingPackage cannot be null"); 42 18136 } 43 18137 44 18138 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, 45 18139 "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground); 46 18140 synchronized(this) { 47 18141 final int callingPid = Binder.getCallingPid(); 48 18142 final int callingUid = Binder.getCallingUid(); 49 18143 final long origId = Binder.clearCallingIdentity(); 50 18144 ComponentName res; 51 18145 try { 52 18146 res = mServices.startServiceLocked(caller, service, 53 18147 resolvedType, callingPid, callingUid, 54 18148 requireForeground, callingPackage, userId); 55 18149 } finally { 56 18150 Binder.restoreCallingIdentity(origId); 57 18151 } 58 18152 return res; 59 18153 } 60 18154 } 61 18155 62 18156 ComponentName startServiceInPackage(int uid, Intent service, String resolvedType, 63 18157 boolean fgRequired, String callingPackage, int userId) 64 18158 throws TransactionTooLargeException { 65 18159 synchronized(this) { 66 18160 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, 67 18161 "startServiceInPackage: " + service + " type=" + resolvedType); 68 18162 final long origId = Binder.clearCallingIdentity(); 69 18163 ComponentName res; 70 18164 try { 71 18165 res = mServices.startServiceLocked(null, service, 72 18166 resolvedType, -1, uid, fgRequired, callingPackage, userId); 73 18167 } finally { 74 18168 Binder.restoreCallingIdentity(origId); 75 18169 } 76 18170 return res; 77 18171 } 78 18172 } 79 18173 80 18174 @Override 81 18175 public int stopService(IApplicationThread caller, Intent service, 82 18176 String resolvedType, int userId) { 83 18177 enforceNotIsolatedCaller("stopService"); 84 18178 // Refuse possible leaked file descriptors 85 18179 if (service != null && service.hasFileDescriptors() == true) { 86 18180 throw new IllegalArgumentException("File descriptors passed in Intent"); 87 18181 } 88 18182 89 18183 synchronized(this) { 90 18184 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 91 18185 } 92 18186 } 93 18187 94 18188 @Override 95 18189 public IBinder peekService(Intent service, String resolvedType, String callingPackage) { 96 18190 enforceNotIsolatedCaller("peekService"); 97 18191 // Refuse possible leaked file descriptors 98 18192 if (service != null && service.hasFileDescriptors() == true) { 99 18193 throw new IllegalArgumentException("File descriptors passed in Intent"); 100 18194 } 101 18195 102 18196 if (callingPackage == null) { 103 18197 throw new IllegalArgumentException("callingPackage cannot be null"); 104 18198 } 105 18199 106 18200 synchronized(this) { 107 18201 return mServices.peekServiceLocked(service, resolvedType, callingPackage); 108 18202 } 109 18203 } 110 18204 111 18205 @Override 112 18206 public boolean stopServiceToken(ComponentName className, IBinder token, 113 18207 int startId) { 114 18208 synchronized(this) { 115 18209 return mServices.stopServiceTokenLocked(className, token, startId); 116 18210 } 117 18211 } 118 18212 119 18213 @Override 120 18214 public void setServiceForeground(ComponentName className, IBinder token, 121 18215 int id, Notification notification, int flags) { 122 18216 synchronized(this) { 123 18217 mServices.setServiceForegroundLocked(className, token, id, notification, flags); 124 18218 } 125 18219 } 126 18220 127 18221 @Override 128 18222 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 129 18223 boolean requireFull, String name, String callerPackage) { 130 18224 return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll, 131 18225 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 132 18226 } 133 18227 134 18228 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 135 18229 String className, int flags) { 136 18230 boolean result = false; 137 18231 // For apps that don't have pre-defined UIDs, check for permission 138 18232 if (UserHandle.getAppId(aInfo.uid) >= FIRST_APPLICATION_UID) { 139 18233 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 140 18234 if (ActivityManager.checkUidPermission( 141 18235 INTERACT_ACROSS_USERS, 142 18236 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 143 18237 ComponentName comp = new ComponentName(aInfo.packageName, className); 144 18238 String msg = "Permission Denial: Component " + comp.flattenToShortString() 145 18239 + " requests FLAG_SINGLE_USER, but app does not hold " 146 18240 + INTERACT_ACROSS_USERS; 147 18241 Slog.w(TAG, msg); 148 18242 throw new SecurityException(msg); 149 18243 } 150 18244 // Permission passed 151 18245 result = true; 152 18246 } 153 18247 } else if ("system".equals(componentProcessName)) { 154 18248 result = true; 155 18249 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 156 18250 // Phone app and persistent apps are allowed to export singleuser providers. 157 18251 result = UserHandle.isSameApp(aInfo.uid, PHONE_UID) 158 18252 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 159 18253 } 160 18254 if (DEBUG_MU) Slog.v(TAG_MU, 161 18255 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x" 162 18256 + Integer.toHexString(flags) + ") = " + result); 163 18257 return result; 164 18258 } 165 18259 166 18260 /** 167 18261 * Checks to see if the caller is in the same app as the singleton 168 18262 * component, or the component is in a special app. It allows special apps 169 18263 * to export singleton components but prevents exporting singleton 170 18264 * components for regular apps. 171 18265 */ 172 18266 boolean isValidSingletonCall(int callingUid, int componentUid) { 173 18267 int componentAppId = UserHandle.getAppId(componentUid); 174 18268 return UserHandle.isSameApp(callingUid, componentUid) 175 18269 || componentAppId == SYSTEM_UID 176 18270 || componentAppId == PHONE_UID 177 18271 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 178 18272 == PackageManager.PERMISSION_GRANTED; 179 18273 } 180 18274 181 18275 public int bindService(IApplicationThread caller, IBinder token, Intent service, 182 18276 String resolvedType, IServiceConnection connection, int flags, String callingPackage, 183 18277 int userId) throws TransactionTooLargeException { 184 18278 enforceNotIsolatedCaller("bindService"); 185 18279 186 18280 // Refuse possible leaked file descriptors 187 18281 if (service != null && service.hasFileDescriptors() == true) { 188 18282 throw new IllegalArgumentException("File descriptors passed in Intent"); 189 18283 } 190 18284 191 18285 if (callingPackage == null) { 192 18286 throw new IllegalArgumentException("callingPackage cannot be null"); 193 18287 } 194 18288 195 18289 synchronized(this) { 196 18290 return mServices.bindServiceLocked(caller, token, service, 197 18291 resolvedType, connection, flags, callingPackage, userId); 198 18292 } 199 18293 } 200 18294 201 18295 public boolean unbindService(IServiceConnection connection) { 202 18296 synchronized (this) { 203 18297 return mServices.unbindServiceLocked(connection); 204 18298 } 205 18299 } 206 18300 207 18301 public void publishService(IBinder token, Intent intent, IBinder service) { 208 18302 // Refuse possible leaked file descriptors 209 18303 if (intent != null && intent.hasFileDescriptors() == true) { 210 18304 throw new IllegalArgumentException("File descriptors passed in Intent"); 211 18305 } 212 18306 213 18307 synchronized(this) { 214 18308 if (!(token instanceof ServiceRecord)) { 215 18309 throw new IllegalArgumentException("Invalid service token"); 216 18310 } 217 18311 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 218 18312 } 219 18313 } 220 18314 221 18315 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 222 18316 // Refuse possible leaked file descriptors 223 18317 if (intent != null && intent.hasFileDescriptors() == true) { 224 18318 throw new IllegalArgumentException("File descriptors passed in Intent"); 225 18319 } 226 18320 227 18321 synchronized(this) { 228 18322 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 229 18323 } 230 18324 } 231 18325 232 18326 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 233 18327 synchronized(this) { 234 18328 if (!(token instanceof ServiceRecord)) { 235 18329 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token); 236 18330 throw new IllegalArgumentException("Invalid service token"); 237 18331 } 238 18332 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 239 18333 } 240 18334 }
备份和恢复
1 18336 // ========================================================= 2 18337 // BACKUP AND RESTORE 3 18338 // ========================================================= 4 18339 5 18340 // Cause the target app to be launched if necessary and its backup agent 6 18341 // instantiated. The backup agent will invoke backupAgentCreated() on the 7 18342 // activity manager to announce its creation. 8 18343 public boolean bindBackupAgent(String packageName, int backupMode, int userId) { 9 18344 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode); 10 18345 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 11 18346 12 18347 IPackageManager pm = AppGlobals.getPackageManager(); 13 18348 ApplicationInfo app = null; 14 18349 try { 15 18350 app = pm.getApplicationInfo(packageName, 0, userId); 16 18351 } catch (RemoteException e) { 17 18352 // can't happen; package manager is process-local 18 18353 } 19 18354 if (app == null) { 20 18355 Slog.w(TAG, "Unable to bind backup agent for " + packageName); 21 18356 return false; 22 18357 } 23 18358 24 18359 int oldBackupUid; 25 18360 int newBackupUid; 26 18361 27 18362 synchronized(this) { 28 18363 // !!! TODO: currently no check here that we're already bound 29 18364 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 30 18365 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 31 18366 synchronized (stats) { 32 18367 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 33 18368 } 34 18369 35 18370 // Backup agent is now in use, its package can't be stopped. 36 18371 try { 37 18372 AppGlobals.getPackageManager().setPackageStoppedState( 38 18373 app.packageName, false, UserHandle.getUserId(app.uid)); 39 18374 } catch (RemoteException e) { 40 18375 } catch (IllegalArgumentException e) { 41 18376 Slog.w(TAG, "Failed trying to unstop package " 42 18377 + app.packageName + ": " + e); 43 18378 } 44 18379 45 18380 BackupRecord r = new BackupRecord(ss, app, backupMode); 46 18381 ComponentName hostingName = 47 18382 (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL) 48 18383 ? new ComponentName(app.packageName, app.backupAgentName) 49 18384 : new ComponentName("android", "FullBackupAgent"); 50 18385 // startProcessLocked() returns existing proc's record if it's already running 51 18386 ProcessRecord proc = startProcessLocked(app.processName, app, 52 18387 false, 0, "backup", hostingName, false, false, false); 53 18388 if (proc == null) { 54 18389 Slog.e(TAG, "Unable to start backup agent process " + r); 55 18390 return false; 56 18391 } 57 18392 58 18393 // If the app is a regular app (uid >= 10000) and not the system server or phone 59 18394 // process, etc, then mark it as being in full backup so that certain calls to the 60 18395 // process can be blocked. This is not reset to false anywhere because we kill the 61 18396 // process after the full backup is done and the ProcessRecord will vaporize anyway. 62 18397 if (UserHandle.isApp(app.uid) && 63 18398 backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) { 64 18399 proc.inFullBackup = true; 65 18400 } 66 18401 r.app = proc; 67 18402 oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1; 68 18403 newBackupUid = proc.inFullBackup ? r.appInfo.uid : -1; 69 18404 mBackupTarget = r; 70 18405 mBackupAppName = app.packageName; 71 18406 72 18407 // Try not to kill the process during backup 73 18408 updateOomAdjLocked(proc, true); 74 18409 75 18410 // If the process is already attached, schedule the creation of the backup agent now. 76 18411 // If it is not yet live, this will be done when it attaches to the framework. 77 18412 if (proc.thread != null) { 78 18413 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc); 79 18414 try { 80 18415 proc.thread.scheduleCreateBackupAgent(app, 81 18416 compatibilityInfoForPackageLocked(app), backupMode); 82 18417 } catch (RemoteException e) { 83 18418 // Will time out on the backup manager side 84 18419 } 85 18420 } else { 86 18421 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach"); 87 18422 } 88 18423 // Invariants: at this point, the target app process exists and the application 89 18424 // is either already running or in the process of coming up. mBackupTarget and 90 18425 // mBackupAppName describe the app, so that when it binds back to the AM we 91 18426 // know that it's scheduled for a backup-agent operation. 92 18427 } 93 18428 94 18429 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class); 95 18430 if (oldBackupUid != -1) { 96 18431 js.removeBackingUpUid(oldBackupUid); 97 18432 } 98 18433 if (newBackupUid != -1) { 99 18434 js.addBackingUpUid(newBackupUid); 100 18435 } 101 18436 102 18437 return true; 103 18438 } 104 18439 105 18440 @Override 106 18441 public void clearPendingBackup() { 107 18442 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup"); 108 18443 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 109 18444 110 18445 synchronized (this) { 111 18446 mBackupTarget = null; 112 18447 mBackupAppName = null; 113 18448 } 114 18449 115 18450 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class); 116 18451 js.clearAllBackingUpUids(); 117 18452 } 118 18453 119 18454 // A backup agent has just come up 120 18455 public void backupAgentCreated(String agentPackageName, IBinder agent) { 121 18456 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName 122 18457 + " = " + agent); 123 18458 124 18459 synchronized(this) { 125 18460 if (!agentPackageName.equals(mBackupAppName)) { 126 18461 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 127 18462 return; 128 18463 } 129 18464 } 130 18465 131 18466 long oldIdent = Binder.clearCallingIdentity(); 132 18467 try { 133 18468 IBackupManager bm = IBackupManager.Stub.asInterface( 134 18469 ServiceManager.getService(Context.BACKUP_SERVICE)); 135 18470 bm.agentConnected(agentPackageName, agent); 136 18471 } catch (RemoteException e) { 137 18472 // can't happen; the backup manager service is local 138 18473 } catch (Exception e) { 139 18474 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 140 18475 e.printStackTrace(); 141 18476 } finally { 142 18477 Binder.restoreCallingIdentity(oldIdent); 143 18478 } 144 18479 } 145 18480 146 18481 // done with this agent 147 18482 public void unbindBackupAgent(ApplicationInfo appInfo) { 148 18483 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo); 149 18484 if (appInfo == null) { 150 18485 Slog.w(TAG, "unbind backup agent for null app"); 151 18486 return; 152 18487 } 153 18488 154 18489 int oldBackupUid; 155 18490 156 18491 synchronized(this) { 157 18492 try { 158 18493 if (mBackupAppName == null) { 159 18494 Slog.w(TAG, "Unbinding backup agent with no active backup"); 160 18495 return; 161 18496 } 162 18497 163 18498 if (!mBackupAppName.equals(appInfo.packageName)) { 164 18499 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 165 18500 return; 166 18501 } 167 18502 168 18503 // Not backing this app up any more; reset its OOM adjustment 169 18504 final ProcessRecord proc = mBackupTarget.app; 170 18505 updateOomAdjLocked(proc, true); 171 18506 proc.inFullBackup = false; 172 18507 173 18508 oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1; 174 18509 175 18510 // If the app crashed during backup, 'thread' will be null here 176 18511 if (proc.thread != null) { 177 18512 try { 178 18513 proc.thread.scheduleDestroyBackupAgent(appInfo, 179 18514 compatibilityInfoForPackageLocked(appInfo)); 180 18515 } catch (Exception e) { 181 18516 Slog.e(TAG, "Exception when unbinding backup agent:"); 182 18517 e.printStackTrace(); 183 18518 } 184 18519 } 185 18520 } finally { 186 18521 mBackupTarget = null; 187 18522 mBackupAppName = null; 188 18523 } 189 18524 } 190 18525 191 18526 if (oldBackupUid != -1) { 192 18527 JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class); 193 18528 js.removeBackingUpUid(oldBackupUid); 194 18529 } 195 18530 }
broadcast相关
1 18531 2 18532 // ========================================================= 3 18533 // BROADCASTS 4 18534 // ========================================================= 5 18535 6 18536 private boolean isInstantApp(ProcessRecord record, String callerPackage, int uid) { 7 18537 if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) { 8 18538 return false; 9 18539 } 10 18540 // Easy case -- we have the app's ProcessRecord. 11 18541 if (record != null) { 12 18542 return record.info.isInstantApp(); 13 18543 } 14 18544 // Otherwise check with PackageManager. 15 18545 if (callerPackage == null) { 16 18546 Slog.e(TAG, "isInstantApp with an application's uid, no record, and no package name"); 17 18547 throw new IllegalArgumentException("Calling application did not provide package name"); 18 18548 } 19 18549 mAppOpsService.checkPackage(uid, callerPackage); 20 18550 try { 21 18551 IPackageManager pm = AppGlobals.getPackageManager(); 22 18552 return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid)); 23 18553 } catch (RemoteException e) { 24 18554 Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e); 25 18555 return true; 26 18556 } 27 18557 } 28 18558 29 18559 boolean isPendingBroadcastProcessLocked(int pid) { 30 18560 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 31 18561 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 32 18562 } 33 18563 34 18564 void skipPendingBroadcastLocked(int pid) { 35 18565 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 36 18566 for (BroadcastQueue queue : mBroadcastQueues) { 37 18567 queue.skipPendingBroadcastLocked(pid); 38 18568 } 39 18569 } 40 18570 41 18571 // The app just attached; send any pending broadcasts that it should receive 42 18572 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 43 18573 boolean didSomething = false; 44 18574 for (BroadcastQueue queue : mBroadcastQueues) { 45 18575 didSomething |= queue.sendPendingBroadcastsLocked(app); 46 18576 } 47 18577 return didSomething; 48 18578 } 49 18579 50 18580 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 51 18581 IIntentReceiver receiver, IntentFilter filter, String permission, int userId, 52 18582 int flags) { 53 18583 enforceNotIsolatedCaller("registerReceiver"); 54 18584 ArrayList<Intent> stickyIntents = null; 55 18585 ProcessRecord callerApp = null; 56 18586 final boolean visibleToInstantApps 57 18587 = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0; 58 18588 int callingUid; 59 18589 int callingPid; 60 18590 boolean instantApp; 61 18591 synchronized(this) { 62 18592 if (caller != null) { 63 18593 callerApp = getRecordForAppLocked(caller); 64 18594 if (callerApp == null) { 65 18595 throw new SecurityException( 66 18596 "Unable to find app for caller " + caller 67 18597 + " (pid=" + Binder.getCallingPid() 68 18598 + ") when registering receiver " + receiver); 69 18599 } 70 18600 if (callerApp.info.uid != SYSTEM_UID && 71 18601 !callerApp.pkgList.containsKey(callerPackage) && 72 18602 !"android".equals(callerPackage)) { 73 18603 throw new SecurityException("Given caller package " + callerPackage 74 18604 + " is not running in process " + callerApp); 75 18605 } 76 18606 callingUid = callerApp.info.uid; 77 18607 callingPid = callerApp.pid; 78 18608 } else { 79 18609 callerPackage = null; 80 18610 callingUid = Binder.getCallingUid(); 81 18611 callingPid = Binder.getCallingPid(); 82 18612 } 83 18613 84 18614 instantApp = isInstantApp(callerApp, callerPackage, callingUid); 85 18615 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true, 86 18616 ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 87 18617 88 18618 Iterator<String> actions = filter.actionsIterator(); 89 18619 if (actions == null) { 90 18620 ArrayList<String> noAction = new ArrayList<String>(1); 91 18621 noAction.add(null); 92 18622 actions = noAction.iterator(); 93 18623 } 94 18624 95 18625 // Collect stickies of users 96 18626 int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) }; 97 18627 while (actions.hasNext()) { 98 18628 String action = actions.next(); 99 18629 for (int id : userIds) { 100 18630 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id); 101 18631 if (stickies != null) { 102 18632 ArrayList<Intent> intents = stickies.get(action); 103 18633 if (intents != null) { 104 18634 if (stickyIntents == null) { 105 18635 stickyIntents = new ArrayList<Intent>(); 106 18636 } 107 18637 stickyIntents.addAll(intents); 108 18638 } 109 18639 } 110 18640 } 111 18641 } 112 18642 } 113 18643 114 18644 ArrayList<Intent> allSticky = null; 115 18645 if (stickyIntents != null) { 116 18646 final ContentResolver resolver = mContext.getContentResolver(); 117 18647 // Look for any matching sticky broadcasts... 118 18648 for (int i = 0, N = stickyIntents.size(); i < N; i++) { 119 18649 Intent intent = stickyIntents.get(i); 120 18650 // Don't provided intents that aren't available to instant apps. 121 18651 if (instantApp && 122 18652 (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) { 123 18653 continue; 124 18654 } 125 18655 // If intent has scheme "content", it will need to acccess 126 18656 // provider that needs to lock mProviderMap in ActivityThread 127 18657 // and also it may need to wait application response, so we 128 18658 // cannot lock ActivityManagerService here. 129 18659 if (filter.match(resolver, intent, true, TAG) >= 0) { 130 18660 if (allSticky == null) { 131 18661 allSticky = new ArrayList<Intent>(); 132 18662 } 133 18663 allSticky.add(intent); 134 18664 } 135 18665 } 136 18666 } 137 18667 138 18668 // The first sticky in the list is returned directly back to the client. 139 18669 Intent sticky = allSticky != null ? allSticky.get(0) : null; 140 18670 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky); 141 18671 if (receiver == null) { 142 18672 return sticky; 143 18673 } 144 18674 145 18675 synchronized (this) { 146 18676 if (callerApp != null && (callerApp.thread == null 147 18677 || callerApp.thread.asBinder() != caller.asBinder())) { 148 18678 // Original caller already died 149 18679 return null; 150 18680 } 151 18681 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 152 18682 if (rl == null) { 153 18683 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 154 18684 userId, receiver); 155 18685 if (rl.app != null) { 156 18686 rl.app.receivers.add(rl); 157 18687 } else { 158 18688 try { 159 18689 receiver.asBinder().linkToDeath(rl, 0); 160 18690 } catch (RemoteException e) { 161 18691 return sticky; 162 18692 } 163 18693 rl.linkedToDeath = true; 164 18694 } 165 18695 mRegisteredReceivers.put(receiver.asBinder(), rl); 166 18696 } else if (rl.uid != callingUid) { 167 18697 throw new IllegalArgumentException( 168 18698 "Receiver requested to register for uid " + callingUid 169 18699 + " was previously registered for uid " + rl.uid 170 18700 + " callerPackage is " + callerPackage); 171 18701 } else if (rl.pid != callingPid) { 172 18702 throw new IllegalArgumentException( 173 18703 "Receiver requested to register for pid " + callingPid 174 18704 + " was previously registered for pid " + rl.pid 175 18705 + " callerPackage is " + callerPackage); 176 18706 } else if (rl.userId != userId) { 177 18707 throw new IllegalArgumentException( 178 18708 "Receiver requested to register for user " + userId 179 18709 + " was previously registered for user " + rl.userId 180 18710 + " callerPackage is " + callerPackage); 181 18711 } 182 18712 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 183 18713 permission, callingUid, userId, instantApp, visibleToInstantApps); 184 18714 rl.add(bf); 185 18715 if (!bf.debugCheck()) { 186 18716 Slog.w(TAG, "==> For Dynamic broadcast"); 187 18717 } 188 18718 mReceiverResolver.addFilter(bf); 189 18719 190 18720 // Enqueue broadcasts for all existing stickies that match 191 18721 // this filter. 192 18722 if (allSticky != null) { 193 18723 ArrayList receivers = new ArrayList(); 194 18724 receivers.add(bf); 195 18725 196 18726 final int stickyCount = allSticky.size(); 197 18727 for (int i = 0; i < stickyCount; i++) { 198 18728 Intent intent = allSticky.get(i); 199 18729 BroadcastQueue queue = broadcastQueueForIntent(intent); 200 18730 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 201 18731 null, -1, -1, false, null, null, AppOpsManager.OP_NONE, null, receivers, 202 18732 null, 0, null, null, false, true, true, -1); 203 18733 queue.enqueueParallelBroadcastLocked(r); 204 18734 queue.scheduleBroadcastsLocked(); 205 18735 } 206 18736 } 207 18737 208 18738 return sticky; 209 18739 } 210 18740 } 211 18741 212 18742 public void unregisterReceiver(IIntentReceiver receiver) { 213 18743 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver); 214 18744 215 18745 final long origId = Binder.clearCallingIdentity(); 216 18746 try { 217 18747 boolean doTrim = false; 218 18748 219 18749 synchronized(this) { 220 18750 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 221 18751 if (rl != null) { 222 18752 final BroadcastRecord r = rl.curBroadcast; 223 18753 if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) { 224 18754 final boolean doNext = r.queue.finishReceiverLocked( 225 18755 r, r.resultCode, r.resultData, r.resultExtras, 226 18756 r.resultAbort, false); 227 18757 if (doNext) { 228 18758 doTrim = true; 229 18759 r.queue.processNextBroadcast(false); 230 18760 } 231 18761 } 232 18762 233 18763 if (rl.app != null) { 234 18764 rl.app.receivers.remove(rl); 235 18765 } 236 18766 removeReceiverLocked(rl); 237 18767 if (rl.linkedToDeath) { 238 18768 rl.linkedToDeath = false; 239 18769 rl.receiver.asBinder().unlinkToDeath(rl, 0); 240 18770 } 241 18771 } 242 18772 } 243 18773 244 18774 // If we actually concluded any broadcasts, we might now be able 245 18775 // to trim the recipients' apps from our working set 246 18776 if (doTrim) { 247 18777 trimApplications(); 248 18778 return; 249 18779 } 250 18780 251 18781 } finally { 252 18782 Binder.restoreCallingIdentity(origId); 253 18783 } 254 18784 } 255 18785 256 18786 void removeReceiverLocked(ReceiverList rl) { 257 18787 mRegisteredReceivers.remove(rl.receiver.asBinder()); 258 18788 for (int i = rl.size() - 1; i >= 0; i--) { 259 18789 mReceiverResolver.removeFilter(rl.get(i)); 260 18790 } 261 18791 } 262 18792 263 18793 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 264 18794 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 265 18795 ProcessRecord r = mLruProcesses.get(i); 266 18796 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 267 18797 try { 268 18798 r.thread.dispatchPackageBroadcast(cmd, packages); 269 18799 } catch (RemoteException ex) { 270 18800 } 271 18801 } 272 18802 } 273 18803 } 274 18804 275 18805 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 276 18806 int callingUid, int[] users) { 277 18807 // TODO: come back and remove this assumption to triage all broadcasts 278 18808 int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING; 279 18809 280 18810 List<ResolveInfo> receivers = null; 281 18811 try { 282 18812 HashSet<ComponentName> singleUserReceivers = null; 283 18813 boolean scannedFirstReceivers = false; 284 18814 for (int user : users) { 285 18815 // Skip users that have Shell restrictions, with exception of always permitted 286 18816 // Shell broadcasts 287 18817 if (callingUid == SHELL_UID 288 18818 && mUserController.hasUserRestriction( 289 18819 UserManager.DISALLOW_DEBUGGING_FEATURES, user) 290 18820 && !isPermittedShellBroadcast(intent)) { 291 18821 continue; 292 18822 } 293 18823 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 294 18824 .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList(); 295 18825 if (user != UserHandle.USER_SYSTEM && newReceivers != null) { 296 18826 // If this is not the system user, we need to check for 297 18827 // any receivers that should be filtered out. 298 18828 for (int i=0; i<newReceivers.size(); i++) { 299 18829 ResolveInfo ri = newReceivers.get(i); 300 18830 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) { 301 18831 newReceivers.remove(i); 302 18832 i--; 303 18833 } 304 18834 } 305 18835 } 306 18836 if (newReceivers != null && newReceivers.size() == 0) { 307 18837 newReceivers = null; 308 18838 } 309 18839 if (receivers == null) { 310 18840 receivers = newReceivers; 311 18841 } else if (newReceivers != null) { 312 18842 // We need to concatenate the additional receivers 313 18843 // found with what we have do far. This would be easy, 314 18844 // but we also need to de-dup any receivers that are 315 18845 // singleUser. 316 18846 if (!scannedFirstReceivers) { 317 18847 // Collect any single user receivers we had already retrieved. 318 18848 scannedFirstReceivers = true; 319 18849 for (int i=0; i<receivers.size(); i++) { 320 18850 ResolveInfo ri = receivers.get(i); 321 18851 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 322 18852 ComponentName cn = new ComponentName( 323 18853 ri.activityInfo.packageName, ri.activityInfo.name); 324 18854 if (singleUserReceivers == null) { 325 18855 singleUserReceivers = new HashSet<ComponentName>(); 326 18856 } 327 18857 singleUserReceivers.add(cn); 328 18858 } 329 18859 } 330 18860 } 331 18861 // Add the new results to the existing results, tracking 332 18862 // and de-dupping single user receivers. 333 18863 for (int i=0; i<newReceivers.size(); i++) { 334 18864 ResolveInfo ri = newReceivers.get(i); 335 18865 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 336 18866 ComponentName cn = new ComponentName( 337 18867 ri.activityInfo.packageName, ri.activityInfo.name); 338 18868 if (singleUserReceivers == null) { 339 18869 singleUserReceivers = new HashSet<ComponentName>(); 340 18870 } 341 18871 if (!singleUserReceivers.contains(cn)) { 342 18872 singleUserReceivers.add(cn); 343 18873 receivers.add(ri); 344 18874 } 345 18875 } else { 346 18876 receivers.add(ri); 347 18877 } 348 18878 } 349 18879 } 350 18880 } 351 18881 } catch (RemoteException ex) { 352 18882 // pm is in same process, this will never happen. 353 18883 } 354 18884 return receivers; 355 18885 } 356 18886 357 18887 private boolean isPermittedShellBroadcast(Intent intent) { 358 18888 // remote bugreport should always be allowed to be taken 359 18889 return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction()); 360 18890 } 361 18891 362 18892 private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp, 363 18893 String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) { 364 18894 if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) { 365 18895 // Don't yell about broadcasts sent via shell 366 18896 return; 367 18897 } 368 18898 369 18899 final String action = intent.getAction(); 370 18900 if (isProtectedBroadcast 371 18901 || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action) 372 18902 || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action) 373 18903 || Intent.ACTION_MEDIA_BUTTON.equals(action) 374 18904 || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action) 375 18905 || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action) 376 18906 || Intent.ACTION_MASTER_CLEAR.equals(action) 377 18907 || Intent.ACTION_FACTORY_RESET.equals(action) 378 18908 || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action) 379 18909 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action) 380 18910 || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action) 381 18911 || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action) 382 18912 || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action) 383 18913 || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action) 384 18914 || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) { 385 18915 // Broadcast is either protected, or it's a public action that 386 18916 // we've relaxed, so it's fine for system internals to send. 387 18917 return; 388 18918 } 389 18919 390 18920 // This broadcast may be a problem... but there are often system components that 391 18921 // want to send an internal broadcast to themselves, which is annoying to have to 392 18922 // explicitly list each action as a protected broadcast, so we will check for that 393 18923 // one safe case and allow it: an explicit broadcast, only being received by something 394 18924 // that has protected itself. 395 18925 if (receivers != null && receivers.size() > 0 396 18926 && (intent.getPackage() != null || intent.getComponent() != null)) { 397 18927 boolean allProtected = true; 398 18928 for (int i = receivers.size()-1; i >= 0; i--) { 399 18929 Object target = receivers.get(i); 400 18930 if (target instanceof ResolveInfo) { 401 18931 ResolveInfo ri = (ResolveInfo)target; 402 18932 if (ri.activityInfo.exported && ri.activityInfo.permission == null) { 403 18933 allProtected = false; 404 18934 break; 405 18935 } 406 18936 } else { 407 18937 BroadcastFilter bf = (BroadcastFilter)target; 408 18938 if (bf.requiredPermission == null) { 409 18939 allProtected = false; 410 18940 break; 411 18941 } 412 18942 } 413 18943 } 414 18944 if (allProtected) { 415 18945 // All safe! 416 18946 return; 417 18947 } 418 18948 } 419 18949 420 18950 // The vast majority of broadcasts sent from system internals 421 18951 // should be protected to avoid security holes, so yell loudly 422 18952 // to ensure we examine these cases. 423 18953 if (callerApp != null) { 424 18954 Log.wtf(TAG, "Sending non-protected broadcast " + action 425 18955 + " from system " + callerApp.toShortString() + " pkg " + callerPackage, 426 18956 new Throwable()); 427 18957 } else { 428 18958 Log.wtf(TAG, "Sending non-protected broadcast " + action 429 18959 + " from system uid " + UserHandle.formatUid(callingUid) 430 18960 + " pkg " + callerPackage, 431 18961 new Throwable()); 432 18962 } 433 18963 } 434 18964 435 18965 final int broadcastIntentLocked(ProcessRecord callerApp, 436 18966 String callerPackage, Intent intent, String resolvedType, 437 18967 IIntentReceiver resultTo, int resultCode, String resultData, 438 18968 Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions, 439 18969 boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) { 440 18970 intent = new Intent(intent); 441 18971 442 18972 final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid); 443 18973 // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS 444 18974 if (callerInstantApp) { 445 18975 intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS); 446 18976 } 447 18977 448 18978 // By default broadcasts do not go to stopped apps. 449 18979 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 450 18980 451 18981 // If we have not finished booting, don't allow this to launch new processes. 452 18982 if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 453 18983 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 454 18984 } 455 18985 456 18986 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, 457 18987 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 458 18988 + " ordered=" + ordered + " userid=" + userId); 459 18989 if ((resultTo != null) && !ordered) { 460 18990 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 461 18991 } 462 18992 463 18993 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true, 464 18994 ALLOW_NON_FULL, "broadcast", callerPackage); 465 18995 466 18996 // Make sure that the user who is receiving this broadcast is running. 467 18997 // If not, we will just skip it. Make an exception for shutdown broadcasts 468 18998 // and upgrade steps. 469 18999 470 19000 if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) { 471 19001 if ((callingUid != SYSTEM_UID 472 19002 || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) 473 19003 && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) { 474 19004 Slog.w(TAG, "Skipping broadcast of " + intent 475 19005 + ": user " + userId + " is stopped"); 476 19006 return ActivityManager.BROADCAST_FAILED_USER_STOPPED; 477 19007 } 478 19008 } 479 19009 480 19010 BroadcastOptions brOptions = null; 481 19011 if (bOptions != null) { 482 19012 brOptions = new BroadcastOptions(bOptions); 483 19013 if (brOptions.getTemporaryAppWhitelistDuration() > 0) { 484 19014 // See if the caller is allowed to do this. Note we are checking against 485 19015 // the actual real caller (not whoever provided the operation as say a 486 19016 // PendingIntent), because that who is actually supplied the arguments. 487 19017 if (checkComponentPermission( 488 19018 android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST, 489 19019 Binder.getCallingPid(), Binder.getCallingUid(), -1, true) 490 19020 != PackageManager.PERMISSION_GRANTED) { 491 19021 String msg = "Permission Denial: " + intent.getAction() 492 19022 + " broadcast from " + callerPackage + " (pid=" + callingPid 493 19023 + ", uid=" + callingUid + ")" 494 19024 + " requires " 495 19025 + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST; 496 19026 Slog.w(TAG, msg); 497 19027 throw new SecurityException(msg); 498 19028 } 499 19029 } 500 19030 } 501 19031 502 19032 // Verify that protected broadcasts are only being sent by system code, 503 19033 // and that system code is only sending protected broadcasts. 504 19034 final String action = intent.getAction(); 505 19035 final boolean isProtectedBroadcast; 506 19036 try { 507 19037 isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action); 508 19038 } catch (RemoteException e) { 509 19039 Slog.w(TAG, "Remote exception", e); 510 19040 return ActivityManager.BROADCAST_SUCCESS; 511 19041 } 512 19042 513 19043 final boolean isCallerSystem; 514 19044 switch (UserHandle.getAppId(callingUid)) { 515 19045 case ROOT_UID: 516 19046 case SYSTEM_UID: 517 19047 case PHONE_UID: 518 19048 case BLUETOOTH_UID: 519 19049 case NFC_UID: 520 19050 isCallerSystem = true; 521 19051 break; 522 19052 default: 523 19053 isCallerSystem = (callerApp != null) && callerApp.persistent; 524 19054 break; 525 19055 } 526 19056 527 19057 // First line security check before anything else: stop non-system apps from 528 19058 // sending protected broadcasts. 529 19059 if (!isCallerSystem) { 530 19060 if (isProtectedBroadcast) { 531 19061 String msg = "Permission Denial: not allowed to send broadcast " 532 19062 + action + " from pid=" 533 19063 + callingPid + ", uid=" + callingUid; 534 19064 Slog.w(TAG, msg); 535 19065 throw new SecurityException(msg); 536 19066 537 19067 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action) 538 19068 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) { 539 19069 // Special case for compatibility: we don't want apps to send this, 540 19070 // but historically it has not been protected and apps may be using it 541 19071 // to poke their own app widget. So, instead of making it protected, 542 19072 // just limit it to the caller. 543 19073 if (callerPackage == null) { 544 19074 String msg = "Permission Denial: not allowed to send broadcast " 545 19075 + action + " from unknown caller."; 546 19076 Slog.w(TAG, msg); 547 19077 throw new SecurityException(msg); 548 19078 } else if (intent.getComponent() != null) { 549 19079 // They are good enough to send to an explicit component... verify 550 19080 // it is being sent to the calling app. 551 19081 if (!intent.getComponent().getPackageName().equals( 552 19082 callerPackage)) { 553 19083 String msg = "Permission Denial: not allowed to send broadcast " 554 19084 + action + " to " 555 19085 + intent.getComponent().getPackageName() + " from " 556 19086 + callerPackage; 557 19087 Slog.w(TAG, msg); 558 19088 throw new SecurityException(msg); 559 19089 } 560 19090 } else { 561 19091 // Limit broadcast to their own package. 562 19092 intent.setPackage(callerPackage); 563 19093 } 564 19094 } 565 19095 } 566 19096 567 19097 if (action != null) { 568 19098 if (getBackgroundLaunchBroadcasts().contains(action)) { 569 19099 if (DEBUG_BACKGROUND_CHECK) { 570 19100 Slog.i(TAG, "Broadcast action " + action + " forcing include-background"); 571 19101 } 572 19102 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); 573 19103 } 574 19104 575 19105 switch (action) { 576 19106 case Intent.ACTION_UID_REMOVED: 577 19107 case Intent.ACTION_PACKAGE_REMOVED: 578 19108 case Intent.ACTION_PACKAGE_CHANGED: 579 19109 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 580 19110 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 581 19111 case Intent.ACTION_PACKAGES_SUSPENDED: 582 19112 case Intent.ACTION_PACKAGES_UNSUSPENDED: 583 19113 // Handle special intents: if this broadcast is from the package 584 19114 // manager about a package being removed, we need to remove all of 585 19115 // its activities from the history stack. 586 19116 if (checkComponentPermission( 587 19117 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 588 19118 callingPid, callingUid, -1, true) 589 19119 != PackageManager.PERMISSION_GRANTED) { 590 19120 String msg = "Permission Denial: " + intent.getAction() 591 19121 + " broadcast from " + callerPackage + " (pid=" + callingPid 592 19122 + ", uid=" + callingUid + ")" 593 19123 + " requires " 594 19124 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 595 19125 Slog.w(TAG, msg); 596 19126 throw new SecurityException(msg); 597 19127 } 598 19128 switch (action) { 599 19129 case Intent.ACTION_UID_REMOVED: 600 19130 final int uid = getUidFromIntent(intent); 601 19131 if (uid >= 0) { 602 19132 mBatteryStatsService.removeUid(uid); 603 19133 mAppOpsService.uidRemoved(uid); 604 19134 } 605 19135 break; 606 19136 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: 607 19137 // If resources are unavailable just force stop all those packages 608 19138 // and flush the attribute cache as well. 609 19139 String list[] = 610 19140 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 611 19141 if (list != null && list.length > 0) { 612 19142 for (int i = 0; i < list.length; i++) { 613 19143 forceStopPackageLocked(list[i], -1, false, true, true, 614 19144 false, false, userId, "storage unmount"); 615 19145 } 616 19146 mRecentTasks.cleanupLocked(UserHandle.USER_ALL); 617 19147 sendPackageBroadcastLocked( 618 19148 ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE, 619 19149 list, userId); 620 19150 } 621 19151 break; 622 19152 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: 623 19153 mRecentTasks.cleanupLocked(UserHandle.USER_ALL); 624 19154 break; 625 19155 case Intent.ACTION_PACKAGE_REMOVED: 626 19156 case Intent.ACTION_PACKAGE_CHANGED: 627 19157 Uri data = intent.getData(); 628 19158 String ssp; 629 19159 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 630 19160 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action); 631 19161 final boolean replacing = 632 19162 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 633 19163 final boolean killProcess = 634 19164 !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false); 635 19165 final boolean fullUninstall = removed && !replacing; 636 19166 if (removed) { 637 19167 if (killProcess) { 638 19168 forceStopPackageLocked(ssp, UserHandle.getAppId( 639 19169 intent.getIntExtra(Intent.EXTRA_UID, -1)), 640 19170 false, true, true, false, fullUninstall, userId, 641 19171 removed ? "pkg removed" : "pkg changed"); 642 19172 } 643 19173 final int cmd = killProcess 644 19174 ? ApplicationThreadConstants.PACKAGE_REMOVED 645 19175 : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL; 646 19176 sendPackageBroadcastLocked(cmd, 647 19177 new String[] {ssp}, userId); 648 19178 if (fullUninstall) { 649 19179 mAppOpsService.packageRemoved( 650 19180 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 651 19181 652 19182 // Remove all permissions granted from/to this package 653 19183 removeUriPermissionsForPackageLocked(ssp, userId, true); 654 19184 655 19185 removeTasksByPackageNameLocked(ssp, userId); 656 19186 657 19187 mServices.forceStopPackageLocked(ssp, userId); 658 19188 659 19189 // Hide the "unsupported display" dialog if necessary. 660 19190 if (mUnsupportedDisplaySizeDialog != null && ssp.equals( 661 19191 mUnsupportedDisplaySizeDialog.getPackageName())) { 662 19192 mUnsupportedDisplaySizeDialog.dismiss(); 663 19193 mUnsupportedDisplaySizeDialog = null; 664 19194 } 665 19195 mCompatModePackages.handlePackageUninstalledLocked(ssp); 666 19196 mBatteryStatsService.notePackageUninstalled(ssp); 667 19197 } 668 19198 } else { 669 19199 if (killProcess) { 670 19200 killPackageProcessesLocked(ssp, UserHandle.getAppId( 671 19201 intent.getIntExtra(Intent.EXTRA_UID, -1)), 672 19202 userId, ProcessList.INVALID_ADJ, 673 19203 false, true, true, false, "change " + ssp); 674 19204 } 675 19205 cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess, 676 19206 intent.getStringArrayExtra( 677 19207 Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST)); 678 19208 } 679 19209 } 680 19210 break; 681 19211 case Intent.ACTION_PACKAGES_SUSPENDED: 682 19212 case Intent.ACTION_PACKAGES_UNSUSPENDED: 683 19213 final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals( 684 19214 intent.getAction()); 685 19215 final String[] packageNames = intent.getStringArrayExtra( 686 19216 Intent.EXTRA_CHANGED_PACKAGE_LIST); 687 19217 final int userHandle = intent.getIntExtra( 688 19218 Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL); 689 19219 690 19220 synchronized(ActivityManagerService.this) { 691 19221 mRecentTasks.onPackagesSuspendedChanged( 692 19222 packageNames, suspended, userHandle); 693 19223 } 694 19224 break; 695 19225 } 696 19226 break; 697 19227 case Intent.ACTION_PACKAGE_REPLACED: 698 19228 { 699 19229 final Uri data = intent.getData(); 700 19230 final String ssp; 701 19231 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) { 702 19232 ApplicationInfo aInfo = null; 703 19233 try { 704 19234 aInfo = AppGlobals.getPackageManager() 705 19235 .getApplicationInfo(ssp, 0 /*flags*/, userId); 706 19236 } catch (RemoteException ignore) {} 707 19237 if (aInfo == null) { 708 19238 Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:" 709 19239 + " ssp=" + ssp + " data=" + data); 710 19240 return ActivityManager.BROADCAST_SUCCESS; 711 19241 } 712 19242 mStackSupervisor.updateActivityApplicationInfoLocked(aInfo); 713 19243 sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED, 714 19244 new String[] {ssp}, userId); 715 19245 } 716 19246 break; 717 19247 } 718 19248 case Intent.ACTION_PACKAGE_ADDED: 719 19249 { 720 19250 // Special case for adding a package: by default turn on compatibility mode. 721 19251 Uri data = intent.getData(); 722 19252 String ssp; 723 19253 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) { 724 19254 final boolean replacing = 725 19255 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 726 19256 mCompatModePackages.handlePackageAddedLocked(ssp, replacing); 727 19257 728 19258 try { 729 19259 ApplicationInfo ai = AppGlobals.getPackageManager(). 730 19260 getApplicationInfo(ssp, 0, 0); 731 19261 mBatteryStatsService.notePackageInstalled(ssp, 732 19262 ai != null ? ai.versionCode : 0); 733 19263 } catch (RemoteException e) { 734 19264 } 735 19265 } 736 19266 break; 737 19267 } 738 19268 case Intent.ACTION_PACKAGE_DATA_CLEARED: 739 19269 { 740 19270 Uri data = intent.getData(); 741 19271 String ssp; 742 19272 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) { 743 19273 // Hide the "unsupported display" dialog if necessary. 744 19274 if (mUnsupportedDisplaySizeDialog != null && ssp.equals( 745 19275 mUnsupportedDisplaySizeDialog.getPackageName())) { 746 19276 mUnsupportedDisplaySizeDialog.dismiss(); 747 19277 mUnsupportedDisplaySizeDialog = null; 748 19278 } 749 19279 mCompatModePackages.handlePackageDataClearedLocked(ssp); 750 19280 } 751 19281 break; 752 19282 } 753 19283 case Intent.ACTION_TIMEZONE_CHANGED: 754 19284 // If this is the time zone changed action, queue up a message that will reset 755 19285 // the timezone of all currently running processes. This message will get 756 19286 // queued up before the broadcast happens. 757 19287 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 758 19288 break; 759 19289 case Intent.ACTION_TIME_CHANGED: 760 19290 // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between 761 19291 // the tri-state value it may contain and "unknown". 762 19292 // For convenience we re-use the Intent extra values. 763 19293 final int NO_EXTRA_VALUE_FOUND = -1; 764 19294 final int timeFormatPreferenceMsgValue = intent.getIntExtra( 765 19295 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, 766 19296 NO_EXTRA_VALUE_FOUND /* defaultValue */); 767 19297 // Only send a message if the time preference is available. 768 19298 if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) { 769 19299 Message updateTimePreferenceMsg = 770 19300 mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG, 771 19301 timeFormatPreferenceMsgValue, 0); 772 19302 mHandler.sendMessage(updateTimePreferenceMsg); 773 19303 } 774 19304 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 775 19305 synchronized (stats) { 776 19306 stats.noteCurrentTimeChangedLocked(); 777 19307 } 778 19308 break; 779 19309 case Intent.ACTION_CLEAR_DNS_CACHE: 780 19310 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 781 19311 break; 782 19312 case Proxy.PROXY_CHANGE_ACTION: 783 19313 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 784 19314 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 785 19315 break; 786 19316 case android.hardware.Camera.ACTION_NEW_PICTURE: 787 19317 case android.hardware.Camera.ACTION_NEW_VIDEO: 788 19318 // In N we just turned these off; in O we are turing them back on partly, 789 19319 // only for registered receivers. This will still address the main problem 790 19320 // (a spam of apps waking up when a picture is taken putting significant 791 19321 // memory pressure on the system at a bad point), while still allowing apps 792 19322 // that are already actively running to know about this happening. 793 19323 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 794 19324 break; 795 19325 case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED: 796 19326 mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG); 797 19327 break; 798 19328 case "com.android.launcher.action.INSTALL_SHORTCUT": 799 19329 // As of O, we no longer support this broadcasts, even for pre-O apps. 800 19330 // Apps should now be using ShortcutManager.pinRequestShortcut(). 801 19331 Log.w(TAG, "Broadcast " + action 802 19332 + " no longer supported. It will not be delivered."); 803 19333 return ActivityManager.BROADCAST_SUCCESS; 804 19334 } 805 19335 806 19336 if (Intent.ACTION_PACKAGE_ADDED.equals(action) || 807 19337 Intent.ACTION_PACKAGE_REMOVED.equals(action) || 808 19338 Intent.ACTION_PACKAGE_REPLACED.equals(action)) { 809 19339 final int uid = getUidFromIntent(intent); 810 19340 if (uid != -1) { 811 19341 final UidRecord uidRec = mActiveUids.get(uid); 812 19342 if (uidRec != null) { 813 19343 uidRec.updateHasInternetPermission(); 814 19344 } 815 19345 } 816 19346 } 817 19347 } 818 19348 819 19349 // Add to the sticky list if requested. 820 19350 if (sticky) { 821 19351 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 822 19352 callingPid, callingUid) 823 19353 != PackageManager.PERMISSION_GRANTED) { 824 19354 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 825 19355 + callingPid + ", uid=" + callingUid 826 19356 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 827 19357 Slog.w(TAG, msg); 828 19358 throw new SecurityException(msg); 829 19359 } 830 19360 if (requiredPermissions != null && requiredPermissions.length > 0) { 831 19361 Slog.w(TAG, "Can't broadcast sticky intent " + intent 832 19362 + " and enforce permissions " + Arrays.toString(requiredPermissions)); 833 19363 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 834 19364 } 835 19365 if (intent.getComponent() != null) { 836 19366 throw new SecurityException( 837 19367 "Sticky broadcasts can't target a specific component"); 838 19368 } 839 19369 // We use userId directly here, since the "all" target is maintained 840 19370 // as a separate set of sticky broadcasts. 841 19371 if (userId != UserHandle.USER_ALL) { 842 19372 // But first, if this is not a broadcast to all users, then 843 19373 // make sure it doesn't conflict with an existing broadcast to 844 19374 // all users. 845 19375 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 846 19376 UserHandle.USER_ALL); 847 19377 if (stickies != null) { 848 19378 ArrayList<Intent> list = stickies.get(intent.getAction()); 849 19379 if (list != null) { 850 19380 int N = list.size(); 851 19381 int i; 852 19382 for (i=0; i<N; i++) { 853 19383 if (intent.filterEquals(list.get(i))) { 854 19384 throw new IllegalArgumentException( 855 19385 "Sticky broadcast " + intent + " for user " 856 19386 + userId + " conflicts with existing global broadcast"); 857 19387 } 858 19388 } 859 19389 } 860 19390 } 861 19391 } 862 19392 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 863 19393 if (stickies == null) { 864 19394 stickies = new ArrayMap<>(); 865 19395 mStickyBroadcasts.put(userId, stickies); 866 19396 } 867 19397 ArrayList<Intent> list = stickies.get(intent.getAction()); 868 19398 if (list == null) { 869 19399 list = new ArrayList<>(); 870 19400 stickies.put(intent.getAction(), list); 871 19401 } 872 19402 final int stickiesCount = list.size(); 873 19403 int i; 874 19404 for (i = 0; i < stickiesCount; i++) { 875 19405 if (intent.filterEquals(list.get(i))) { 876 19406 // This sticky already exists, replace it. 877 19407 list.set(i, new Intent(intent)); 878 19408 break; 879 19409 } 880 19410 } 881 19411 if (i >= stickiesCount) { 882 19412 list.add(new Intent(intent)); 883 19413 } 884 19414 } 885 19415 886 19416 int[] users; 887 19417 if (userId == UserHandle.USER_ALL) { 888 19418 // Caller wants broadcast to go to all started users. 889 19419 users = mUserController.getStartedUserArrayLocked(); 890 19420 } else { 891 19421 // Caller wants broadcast to go to one specific user. 892 19422 users = new int[] {userId}; 893 19423 } 894 19424 895 19425 // Figure out who all will receive this broadcast. 896 19426 List receivers = null; 897 19427 List<BroadcastFilter> registeredReceivers = null; 898 19428 // Need to resolve the intent to interested receivers... 899 19429 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 900 19430 == 0) { 901 19431 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); 902 19432 } 903 19433 if (intent.getComponent() == null) { 904 19434 if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) { 905 19435 // Query one target user at a time, excluding shell-restricted users 906 19436 for (int i = 0; i < users.length; i++) { 907 19437 if (mUserController.hasUserRestriction( 908 19438 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { 909 19439 continue; 910 19440 } 911 19441 List<BroadcastFilter> registeredReceiversForUser = 912 19442 mReceiverResolver.queryIntent(intent, 913 19443 resolvedType, false /*defaultOnly*/, users[i]); 914 19444 if (registeredReceivers == null) { 915 19445 registeredReceivers = registeredReceiversForUser; 916 19446 } else if (registeredReceiversForUser != null) { 917 19447 registeredReceivers.addAll(registeredReceiversForUser); 918 19448 } 919 19449 } 920 19450 } else { 921 19451 registeredReceivers = mReceiverResolver.queryIntent(intent, 922 19452 resolvedType, false /*defaultOnly*/, userId); 923 19453 } 924 19454 } 925 19455 926 19456 final boolean replacePending = 927 19457 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 928 19458 929 19459 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction() 930 19460 + " replacePending=" + replacePending); 931 19461 932 19462 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 933 19463 if (!ordered && NR > 0) { 934 19464 // If we are not serializing this broadcast, then send the 935 19465 // registered receivers separately so they don't wait for the 936 19466 // components to be launched. 937 19467 if (isCallerSystem) { 938 19468 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid, 939 19469 isProtectedBroadcast, registeredReceivers); 940 19470 } 941 19471 final BroadcastQueue queue = broadcastQueueForIntent(intent); 942 19472 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 943 19473 callerPackage, callingPid, callingUid, callerInstantApp, resolvedType, 944 19474 requiredPermissions, appOp, brOptions, registeredReceivers, resultTo, 945 19475 resultCode, resultData, resultExtras, ordered, sticky, false, userId); 946 19476 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r); 947 19477 final boolean replaced = replacePending 948 19478 && (queue.replaceParallelBroadcastLocked(r) != null); 949 19479 // Note: We assume resultTo is null for non-ordered broadcasts. 950 19480 if (!replaced) { 951 19481 queue.enqueueParallelBroadcastLocked(r); 952 19482 queue.scheduleBroadcastsLocked(); 953 19483 } 954 19484 registeredReceivers = null; 955 19485 NR = 0; 956 19486 } 957 19487 958 19488 // Merge into one list. 959 19489 int ir = 0; 960 19490 if (receivers != null) { 961 19491 // A special case for PACKAGE_ADDED: do not allow the package 962 19492 // being added to see this broadcast. This prevents them from 963 19493 // using this as a back door to get run as soon as they are 964 19494 // installed. Maybe in the future we want to have a special install 965 19495 // broadcast or such for apps, but we'd like to deliberately make 966 19496 // this decision. 967 19497 String skipPackages[] = null; 968 19498 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 969 19499 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 970 19500 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 971 19501 Uri data = intent.getData(); 972 19502 if (data != null) { 973 19503 String pkgName = data.getSchemeSpecificPart(); 974 19504 if (pkgName != null) { 975 19505 skipPackages = new String[] { pkgName }; 976 19506 } 977 19507 } 978 19508 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 979 19509 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 980 19510 } 981 19511 if (skipPackages != null && (skipPackages.length > 0)) { 982 19512 for (String skipPackage : skipPackages) { 983 19513 if (skipPackage != null) { 984 19514 int NT = receivers.size(); 985 19515 for (int it=0; it<NT; it++) { 986 19516 ResolveInfo curt = (ResolveInfo)receivers.get(it); 987 19517 if (curt.activityInfo.packageName.equals(skipPackage)) { 988 19518 receivers.remove(it); 989 19519 it--; 990 19520 NT--; 991 19521 } 992 19522 } 993 19523 } 994 19524 } 995 19525 } 996 19526 997 19527 int NT = receivers != null ? receivers.size() : 0; 998 19528 int it = 0; 999 19529 ResolveInfo curt = null; 1000 19530 BroadcastFilter curr = null; 1001 19531 while (it < NT && ir < NR) { 1002 19532 if (curt == null) { 1003 19533 curt = (ResolveInfo)receivers.get(it); 1004 19534 } 1005 19535 if (curr == null) { 1006 19536 curr = registeredReceivers.get(ir); 1007 19537 } 1008 19538 if (curr.getPriority() >= curt.priority) { 1009 19539 // Insert this broadcast record into the final list. 1010 19540 receivers.add(it, curr); 1011 19541 ir++; 1012 19542 curr = null; 1013 19543 it++; 1014 19544 NT++; 1015 19545 } else { 1016 19546 // Skip to the next ResolveInfo in the final list. 1017 19547 it++; 1018 19548 curt = null; 1019 19549 } 1020 19550 } 1021 19551 } 1022 19552 while (ir < NR) { 1023 19553 if (receivers == null) { 1024 19554 receivers = new ArrayList(); 1025 19555 } 1026 19556 receivers.add(registeredReceivers.get(ir)); 1027 19557 ir++; 1028 19558 } 1029 19559 1030 19560 if (isCallerSystem) { 1031 19561 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid, 1032 19562 isProtectedBroadcast, receivers); 1033 19563 } 1034 19564 1035 19565 if ((receivers != null && receivers.size() > 0) 1036 19566 || resultTo != null) { 1037 19567 BroadcastQueue queue = broadcastQueueForIntent(intent); 1038 19568 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 1039 19569 callerPackage, callingPid, callingUid, callerInstantApp, resolvedType, 1040 19570 requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode, 1041 19571 resultData, resultExtras, ordered, sticky, false, userId); 1042 19572 1043 19573 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r 1044 19574 + ": prev had " + queue.mOrderedBroadcasts.size()); 1045 19575 if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST, 1046 19576 "Enqueueing broadcast " + r.intent.getAction()); 1047 19577 1048 19578 final BroadcastRecord oldRecord = 1049 19579 replacePending ? queue.replaceOrderedBroadcastLocked(r) : null; 1050 19580 if (oldRecord != null) { 1051 19581 // Replaced, fire the result-to receiver. 1052 19582 if (oldRecord.resultTo != null) { 1053 19583 final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent); 1054 19584 try { 1055 19585 oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo, 1056 19586 oldRecord.intent, 1057 19587 Activity.RESULT_CANCELED, null, null, 1058 19588 false, false, oldRecord.userId); 1059 19589 } catch (RemoteException e) { 1060 19590 Slog.w(TAG, "Failure [" 1061 19591 + queue.mQueueName + "] sending broadcast result of " 1062 19592 + intent, e); 1063 19593 1064 19594 } 1065 19595 } 1066 19596 } else { 1067 19597 queue.enqueueOrderedBroadcastLocked(r); 1068 19598 queue.scheduleBroadcastsLocked(); 1069 19599 } 1070 19600 } else { 1071 19601 // There was nobody interested in the broadcast, but we still want to record 1072 19602 // that it happened. 1073 19603 if (intent.getComponent() == null && intent.getPackage() == null 1074 19604 && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 1075 19605 // This was an implicit broadcast... let's record it for posterity. 1076 19606 addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0); 1077 19607 } 1078 19608 } 1079 19609 1080 19610 return ActivityManager.BROADCAST_SUCCESS; 1081 19611 } 1082 19612 1083 19613 /** 1084 19614 * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1 1085 19615 */ 1086 19616 private int getUidFromIntent(Intent intent) { 1087 19617 if (intent == null) { 1088 19618 return -1; 1089 19619 } 1090 19620 final Bundle intentExtras = intent.getExtras(); 1091 19621 return intent.hasExtra(Intent.EXTRA_UID) 1092 19622 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 1093 19623 } 1094 19624 1095 19625 final void rotateBroadcastStatsIfNeededLocked() { 1096 19626 final long now = SystemClock.elapsedRealtime(); 1097 19627 if (mCurBroadcastStats == null || 1098 19628 (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) { 1099 19629 mLastBroadcastStats = mCurBroadcastStats; 1100 19630 if (mLastBroadcastStats != null) { 1101 19631 mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime(); 1102 19632 mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis(); 1103 19633 } 1104 19634 mCurBroadcastStats = new BroadcastStats(); 1105 19635 } 1106 19636 } 1107 19637 1108 19638 final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount, 1109 19639 int skipCount, long dispatchTime) { 1110 19640 rotateBroadcastStatsIfNeededLocked(); 1111 19641 mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime); 1112 19642 } 1113 19643 1114 19644 final void addBackgroundCheckViolationLocked(String action, String targetPackage) { 1115 19645 rotateBroadcastStatsIfNeededLocked(); 1116 19646 mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage); 1117 19647 } 1118 19648 1119 19649 final Intent verifyBroadcastLocked(Intent intent) { 1120 19650 // Refuse possible leaked file descriptors 1121 19651 if (intent != null && intent.hasFileDescriptors() == true) { 1122 19652 throw new IllegalArgumentException("File descriptors passed in Intent"); 1123 19653 } 1124 19654 1125 19655 int flags = intent.getFlags(); 1126 19656 1127 19657 if (!mProcessesReady) { 1128 19658 // if the caller really truly claims to know what they're doing, go 1129 19659 // ahead and allow the broadcast without launching any receivers 1130 19660 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 1131 19661 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed. 1132 19662 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 1133 19663 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 1134 19664 + " before boot completion"); 1135 19665 throw new IllegalStateException("Cannot broadcast before boot completed"); 1136 19666 } 1137 19667 } 1138 19668 1139 19669 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 1140 19670 throw new IllegalArgumentException( 1141 19671 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 1142 19672 } 1143 19673 1144 19674 if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) { 1145 19675 switch (Binder.getCallingUid()) { 1146 19676 case ROOT_UID: 1147 19677 case SHELL_UID: 1148 19678 break; 1149 19679 default: 1150 19680 Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID " 1151 19681 + Binder.getCallingUid()); 1152 19682 intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL); 1153 19683 break; 1154 19684 } 1155 19685 } 1156 19686 1157 19687 return intent; 1158 19688 } 1159 19689 1160 19690 public final int broadcastIntent(IApplicationThread caller, 1161 19691 Intent intent, String resolvedType, IIntentReceiver resultTo, 1162 19692 int resultCode, String resultData, Bundle resultExtras, 1163 19693 String[] requiredPermissions, int appOp, Bundle bOptions, 1164 19694 boolean serialized, boolean sticky, int userId) { 1165 19695 enforceNotIsolatedCaller("broadcastIntent"); 1166 19696 synchronized(this) { 1167 19697 intent = verifyBroadcastLocked(intent); 1168 19698 1169 19699 final ProcessRecord callerApp = getRecordForAppLocked(caller); 1170 19700 final int callingPid = Binder.getCallingPid(); 1171 19701 final int callingUid = Binder.getCallingUid(); 1172 19702 final long origId = Binder.clearCallingIdentity(); 1173 19703 int res = broadcastIntentLocked(callerApp, 1174 19704 callerApp != null ? callerApp.info.packageName : null, 1175 19705 intent, resolvedType, resultTo, resultCode, resultData, resultExtras, 1176 19706 requiredPermissions, appOp, bOptions, serialized, sticky, 1177 19707 callingPid, callingUid, userId); 1178 19708 Binder.restoreCallingIdentity(origId); 1179 19709 return res; 1180 19710 } 1181 19711 } 1182 19712 1183 19713 1184 19714 int broadcastIntentInPackage(String packageName, int uid, 1185 19715 Intent intent, String resolvedType, IIntentReceiver resultTo, 1186 19716 int resultCode, String resultData, Bundle resultExtras, 1187 19717 String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky, 1188 19718 int userId) { 1189 19719 synchronized(this) { 1190 19720 intent = verifyBroadcastLocked(intent); 1191 19721 1192 19722 final long origId = Binder.clearCallingIdentity(); 1193 19723 String[] requiredPermissions = requiredPermission == null ? null 1194 19724 : new String[] {requiredPermission}; 1195 19725 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 1196 19726 resultTo, resultCode, resultData, resultExtras, 1197 19727 requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized, 1198 19728 sticky, -1, uid, userId); 1199 19729 Binder.restoreCallingIdentity(origId); 1200 19730 return res; 1201 19731 } 1202 19732 } 1203 19733 1204 19734 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 1205 19735 // Refuse possible leaked file descriptors 1206 19736 if (intent != null && intent.hasFileDescriptors() == true) { 1207 19737 throw new IllegalArgumentException("File descriptors passed in Intent"); 1208 19738 } 1209 19739 1210 19740 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 1211 19741 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 1212 19742 1213 19743 synchronized(this) { 1214 19744 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 1215 19745 != PackageManager.PERMISSION_GRANTED) { 1216 19746 String msg = "Permission Denial: unbroadcastIntent() from pid=" 1217 19747 + Binder.getCallingPid() 1218 19748 + ", uid=" + Binder.getCallingUid() 1219 19749 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 1220 19750 Slog.w(TAG, msg); 1221 19751 throw new SecurityException(msg); 1222 19752 } 1223 19753 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 1224 19754 if (stickies != null) { 1225 19755 ArrayList<Intent> list = stickies.get(intent.getAction()); 1226 19756 if (list != null) { 1227 19757 int N = list.size(); 1228 19758 int i; 1229 19759 for (i=0; i<N; i++) { 1230 19760 if (intent.filterEquals(list.get(i))) { 1231 19761 list.remove(i); 1232 19762 break; 1233 19763 } 1234 19764 } 1235 19765 if (list.size() <= 0) { 1236 19766 stickies.remove(intent.getAction()); 1237 19767 } 1238 19768 } 1239 19769 if (stickies.size() <= 0) { 1240 19770 mStickyBroadcasts.remove(userId); 1241 19771 } 1242 19772 } 1243 19773 } 1244 19774 } 1245 19775 1246 19776 void backgroundServicesFinishedLocked(int userId) { 1247 19777 for (BroadcastQueue queue : mBroadcastQueues) { 1248 19778 queue.backgroundServicesFinishedLocked(userId); 1249 19779 } 1250 19780 } 1251 19781 1252 19782 public void finishReceiver(IBinder who, int resultCode, String resultData, 1253 19783 Bundle resultExtras, boolean resultAbort, int flags) { 1254 19784 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who); 1255 19785 1256 19786 // Refuse possible leaked file descriptors 1257 19787 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 1258 19788 throw new IllegalArgumentException("File descriptors passed in Bundle"); 1259 19789 } 1260 19790 1261 19791 final long origId = Binder.clearCallingIdentity(); 1262 19792 try { 1263 19793 boolean doNext = false; 1264 19794 BroadcastRecord r; 1265 19795 1266 19796 synchronized(this) { 1267 19797 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0 1268 19798 ? mFgBroadcastQueue : mBgBroadcastQueue; 1269 19799 r = queue.getMatchingOrderedReceiver(who); 1270 19800 if (r != null) { 1271 19801 doNext = r.queue.finishReceiverLocked(r, resultCode, 1272 19802 resultData, resultExtras, resultAbort, true); 1273 19803 } 1274 19804 } 1275 19805 1276 19806 if (doNext) { 1277 19807 r.queue.processNextBroadcast(false); 1278 19808 } 1279 19809 trimApplications(); 1280 19810 } finally { 1281 19811 Binder.restoreCallingIdentity(origId); 1282 19812 } 1283 19813 }
instrumentation相关
1 19815 // ========================================================= 2 19816 // INSTRUMENTATION 3 19817 // ========================================================= 4 19818 5 19819 public boolean startInstrumentation(ComponentName className, 6 19820 String profileFile, int flags, Bundle arguments, 7 19821 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 8 19822 int userId, String abiOverride) { 9 19823 enforceNotIsolatedCaller("startInstrumentation"); 10 19824 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 11 19825 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 12 19826 // Refuse possible leaked file descriptors 13 19827 if (arguments != null && arguments.hasFileDescriptors()) { 14 19828 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15 19829 } 16 19830 17 19831 synchronized(this) { 18 19832 InstrumentationInfo ii = null; 19 19833 ApplicationInfo ai = null; 20 19834 try { 21 19835 ii = mContext.getPackageManager().getInstrumentationInfo( 22 19836 className, STOCK_PM_FLAGS); 23 19837 ai = AppGlobals.getPackageManager().getApplicationInfo( 24 19838 ii.targetPackage, STOCK_PM_FLAGS, userId); 25 19839 } catch (PackageManager.NameNotFoundException e) { 26 19840 } catch (RemoteException e) { 27 19841 } 28 19842 if (ii == null) { 29 19843 reportStartInstrumentationFailureLocked(watcher, className, 30 19844 "Unable to find instrumentation info for: " + className); 31 19845 return false; 32 19846 } 33 19847 if (ai == null) { 34 19848 reportStartInstrumentationFailureLocked(watcher, className, 35 19849 "Unable to find instrumentation target package: " + ii.targetPackage); 36 19850 return false; 37 19851 } 38 19852 if (!ai.hasCode()) { 39 19853 reportStartInstrumentationFailureLocked(watcher, className, 40 19854 "Instrumentation target has no code: " + ii.targetPackage); 41 19855 return false; 42 19856 } 43 19857 44 19858 int match = mContext.getPackageManager().checkSignatures( 45 19859 ii.targetPackage, ii.packageName); 46 19860 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 47 19861 String msg = "Permission Denial: starting instrumentation " 48 19862 + className + " from pid=" 49 19863 + Binder.getCallingPid() 50 19864 + ", uid=" + Binder.getCallingPid() 51 19865 + " not allowed because package " + ii.packageName 52 19866 + " does not have a signature matching the target " 53 19867 + ii.targetPackage; 54 19868 reportStartInstrumentationFailureLocked(watcher, className, msg); 55 19869 throw new SecurityException(msg); 56 19870 } 57 19871 58 19872 ActiveInstrumentation activeInstr = new ActiveInstrumentation(this); 59 19873 activeInstr.mClass = className; 60 19874 String defProcess = ai.processName;; 61 19875 if (ii.targetProcesses == null) { 62 19876 activeInstr.mTargetProcesses = new String[]{ai.processName}; 63 19877 } else if (ii.targetProcesses.equals("*")) { 64 19878 activeInstr.mTargetProcesses = new String[0]; 65 19879 } else { 66 19880 activeInstr.mTargetProcesses = ii.targetProcesses.split(","); 67 19881 defProcess = activeInstr.mTargetProcesses[0]; 68 19882 } 69 19883 activeInstr.mTargetInfo = ai; 70 19884 activeInstr.mProfileFile = profileFile; 71 19885 activeInstr.mArguments = arguments; 72 19886 activeInstr.mWatcher = watcher; 73 19887 activeInstr.mUiAutomationConnection = uiAutomationConnection; 74 19888 activeInstr.mResultClass = className; 75 19889 76 19890 final long origId = Binder.clearCallingIdentity(); 77 19891 // Instrumentation can kill and relaunch even persistent processes 78 19892 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 79 19893 "start instr"); 80 19894 ProcessRecord app = addAppLocked(ai, defProcess, false, abiOverride); 81 19895 app.instr = activeInstr; 82 19896 activeInstr.mFinished = false; 83 19897 activeInstr.mRunningProcesses.add(app); 84 19898 if (!mActiveInstrumentation.contains(activeInstr)) { 85 19899 mActiveInstrumentation.add(activeInstr); 86 19900 } 87 19901 Binder.restoreCallingIdentity(origId); 88 19902 } 89 19903 90 19904 return true; 91 19905 } 92 19906 93 19907 /** 94 19908 * Report errors that occur while attempting to start Instrumentation. Always writes the 95 19909 * error to the logs, but if somebody is watching, send the report there too. This enables 96 19910 * the "am" command to report errors with more information. 97 19911 * 98 19912 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 99 19913 * @param cn The component name of the instrumentation. 100 19914 * @param report The error report. 101 19915 */ 102 19916 private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher, 103 19917 ComponentName cn, String report) { 104 19918 Slog.w(TAG, report); 105 19919 if (watcher != null) { 106 19920 Bundle results = new Bundle(); 107 19921 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 108 19922 results.putString("Error", report); 109 19923 mInstrumentationReporter.reportStatus(watcher, cn, -1, results); 110 19924 } 111 19925 } 112 19926 113 19927 void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) { 114 19928 if (app.instr == null) { 115 19929 Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app); 116 19930 return; 117 19931 } 118 19932 119 19933 if (!app.instr.mFinished && results != null) { 120 19934 if (app.instr.mCurResults == null) { 121 19935 app.instr.mCurResults = new Bundle(results); 122 19936 } else { 123 19937 app.instr.mCurResults.putAll(results); 124 19938 } 125 19939 } 126 19940 } 127 19941 128 19942 public void addInstrumentationResults(IApplicationThread target, Bundle results) { 129 19943 int userId = UserHandle.getCallingUserId(); 130 19944 // Refuse possible leaked file descriptors 131 19945 if (results != null && results.hasFileDescriptors()) { 132 19946 throw new IllegalArgumentException("File descriptors passed in Intent"); 133 19947 } 134 19948 135 19949 synchronized(this) { 136 19950 ProcessRecord app = getRecordForAppLocked(target); 137 19951 if (app == null) { 138 19952 Slog.w(TAG, "addInstrumentationResults: no app for " + target); 139 19953 return; 140 19954 } 141 19955 final long origId = Binder.clearCallingIdentity(); 142 19956 addInstrumentationResultsLocked(app, results); 143 19957 Binder.restoreCallingIdentity(origId); 144 19958 } 145 19959 } 146 19960 147 19961 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 148 19962 if (app.instr == null) { 149 19963 Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app); 150 19964 return; 151 19965 } 152 19966 153 19967 if (!app.instr.mFinished) { 154 19968 if (app.instr.mWatcher != null) { 155 19969 Bundle finalResults = app.instr.mCurResults; 156 19970 if (finalResults != null) { 157 19971 if (app.instr.mCurResults != null && results != null) { 158 19972 finalResults.putAll(results); 159 19973 } 160 19974 } else { 161 19975 finalResults = results; 162 19976 } 163 19977 mInstrumentationReporter.reportFinished(app.instr.mWatcher, 164 19978 app.instr.mClass, resultCode, finalResults); 165 19979 } 166 19980 167 19981 // Can't call out of the system process with a lock held, so post a message. 168 19982 if (app.instr.mUiAutomationConnection != null) { 169 19983 mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG, 170 19984 app.instr.mUiAutomationConnection).sendToTarget(); 171 19985 } 172 19986 app.instr.mFinished = true; 173 19987 } 174 19988 175 19989 app.instr.removeProcess(app); 176 19990 app.instr = null; 177 19991 178 19992 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 179 19993 "finished inst"); 180 19994 } 181 19995 182 19996 public void finishInstrumentation(IApplicationThread target, 183 19997 int resultCode, Bundle results) { 184 19998 int userId = UserHandle.getCallingUserId(); 185 19999 // Refuse possible leaked file descriptors 186 20000 if (results != null && results.hasFileDescriptors()) { 187 20001 throw new IllegalArgumentException("File descriptors passed in Intent"); 188 20002 } 189 20003 190 20004 synchronized(this) { 191 20005 ProcessRecord app = getRecordForAppLocked(target); 192 20006 if (app == null) { 193 20007 Slog.w(TAG, "finishInstrumentation: no app for " + target); 194 20008 return; 195 20009 } 196 20010 final long origId = Binder.clearCallingIdentity(); 197 20011 finishInstrumentationLocked(app, resultCode, results); 198 20012 Binder.restoreCallingIdentity(origId); 199 20013 } 200 20014 }
配置相关
1 20015 2 20016 // ========================================================= 3 20017 // CONFIGURATION 4 20018 // ========================================================= 5 20019 6 20020 public ConfigurationInfo getDeviceConfigurationInfo() { 7 20021 ConfigurationInfo config = new ConfigurationInfo(); 8 20022 synchronized (this) { 9 20023 final Configuration globalConfig = getGlobalConfiguration(); 10 20024 config.reqTouchScreen = globalConfig.touchscreen; 11 20025 config.reqKeyboardType = globalConfig.keyboard; 12 20026 config.reqNavigation = globalConfig.navigation; 13 20027 if (globalConfig.navigation == Configuration.NAVIGATION_DPAD 14 20028 || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) { 15 20029 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 16 20030 } 17 20031 if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED 18 20032 && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) { 19 20033 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 20 20034 } 21 20035 config.reqGlEsVersion = GL_ES_VERSION; 22 20036 } 23 20037 return config; 24 20038 } 25 20039 26 20040 ActivityStack getFocusedStack() { 27 20041 return mStackSupervisor.getFocusedStack(); 28 20042 } 29 20043 30 20044 @Override 31 20045 public int getFocusedStackId() throws RemoteException { 32 20046 ActivityStack focusedStack = getFocusedStack(); 33 20047 if (focusedStack != null) { 34 20048 return focusedStack.getStackId(); 35 20049 } 36 20050 return -1; 37 20051 } 38 20052 39 20053 public Configuration getConfiguration() { 40 20054 Configuration ci; 41 20055 synchronized(this) { 42 20056 ci = new Configuration(getGlobalConfiguration()); 43 20057 ci.userSetLocale = false; 44 20058 } 45 20059 return ci; 46 20060 } 47 20061 48 20062 @Override 49 20063 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException { 50 20064 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()"); 51 20065 synchronized (this) { 52 20066 mSuppressResizeConfigChanges = suppress; 53 20067 } 54 20068 } 55 20069 56 20070 /** 57 20071 * NOTE: For the pinned stack, this method is usually called after the bounds animation has 58 20072 * animated the stack to the fullscreen, but can also be called if we are relaunching an 59 20073 * activity and clearing the task at the same time. 60 20074 */ 61 20075 @Override 62 20076 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) { 63 20077 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()"); 64 20078 if (StackId.isHomeOrRecentsStack(fromStackId)) { 65 20079 throw new IllegalArgumentException("You can't move tasks from the home/recents stack."); 66 20080 } 67 20081 synchronized (this) { 68 20082 final long origId = Binder.clearCallingIdentity(); 69 20083 try { 70 20084 mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop); 71 20085 } finally { 72 20086 Binder.restoreCallingIdentity(origId); 73 20087 } 74 20088 } 75 20089 } 76 20090 77 20091 @Override 78 20092 public void updatePersistentConfiguration(Configuration values) { 79 20093 enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()"); 80 20094 enforceWriteSettingsPermission("updatePersistentConfiguration()"); 81 20095 if (values == null) { 82 20096 throw new NullPointerException("Configuration must not be null"); 83 20097 } 84 20098 85 20099 int userId = UserHandle.getCallingUserId(); 86 20100 87 20101 synchronized(this) { 88 20102 updatePersistentConfigurationLocked(values, userId); 89 20103 } 90 20104 } 91 20105 92 20106 private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) { 93 20107 final long origId = Binder.clearCallingIdentity(); 94 20108 try { 95 20109 updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */); 96 20110 } finally { 97 20111 Binder.restoreCallingIdentity(origId); 98 20112 } 99 20113 } 100 20114 101 20115 private void updateFontScaleIfNeeded(@UserIdInt int userId) { 102 20116 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(), 103 20117 FONT_SCALE, 1.0f, userId); 104 20118 105 20119 synchronized (this) { 106 20120 if (getGlobalConfiguration().fontScale == scaleFactor) { 107 20121 return; 108 20122 } 109 20123 110 20124 final Configuration configuration 111 20125 = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY); 112 20126 configuration.fontScale = scaleFactor; 113 20127 updatePersistentConfigurationLocked(configuration, userId); 114 20128 } 115 20129 } 116 20130 117 20131 private void enforceWriteSettingsPermission(String func) { 118 20132 int uid = Binder.getCallingUid(); 119 20133 if (uid == ROOT_UID) { 120 20134 return; 121 20135 } 122 20136 123 20137 if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid, 124 20138 Settings.getPackageNameForUid(mContext, uid), false)) { 125 20139 return; 126 20140 } 127 20141 128 20142 String msg = "Permission Denial: " + func + " from pid=" 129 20143 + Binder.getCallingPid() 130 20144 + ", uid=" + uid 131 20145 + " requires " + android.Manifest.permission.WRITE_SETTINGS; 132 20146 Slog.w(TAG, msg); 133 20147 throw new SecurityException(msg); 134 20148 } 135 20149 136 20150 @Override 137 20151 public boolean updateConfiguration(Configuration values) { 138 20152 enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()"); 139 20153 140 20154 synchronized(this) { 141 20155 if (values == null && mWindowManager != null) { 142 20156 // sentinel: fetch the current configuration from the window manager 143 20157 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY); 144 20158 } 145 20159 146 20160 if (mWindowManager != null) { 147 20161 // Update OOM levels based on display size. 148 20162 mProcessList.applyDisplaySize(mWindowManager); 149 20163 } 150 20164 151 20165 final long origId = Binder.clearCallingIdentity(); 152 20166 try { 153 20167 if (values != null) { 154 20168 Settings.System.clearConfiguration(values); 155 20169 } 156 20170 updateConfigurationLocked(values, null, false, false /* persistent */, 157 20171 UserHandle.USER_NULL, false /* deferResume */, 158 20172 mTmpUpdateConfigurationResult); 159 20173 return mTmpUpdateConfigurationResult.changes != 0; 160 20174 } finally { 161 20175 Binder.restoreCallingIdentity(origId); 162 20176 } 163 20177 } 164 20178 } 165 20179 166 20180 void updateUserConfigurationLocked() { 167 20181 final Configuration configuration = new Configuration(getGlobalConfiguration()); 168 20182 final int currentUserId = mUserController.getCurrentUserIdLocked(); 169 20183 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration, 170 20184 currentUserId, Settings.System.canWrite(mContext)); 171 20185 updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */, 172 20186 false /* persistent */, currentUserId, false /* deferResume */); 173 20187 } 174 20188 175 20189 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting, 176 20190 boolean initLocale) { 177 20191 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */); 178 20192 } 179 20193 180 20194 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting, 181 20195 boolean initLocale, boolean deferResume) { 182 20196 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user 183 20197 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */, 184 20198 UserHandle.USER_NULL, deferResume); 185 20199 } 186 20200 187 20201 // To cache the list of supported system locales 188 20202 private String[] mSupportedSystemLocales = null; 189 20203 190 20204 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting, 191 20205 boolean initLocale, boolean persistent, int userId, boolean deferResume) { 192 20206 return updateConfigurationLocked(values, starting, initLocale, persistent, userId, 193 20207 deferResume, null /* result */); 194 20208 } 195 20209 196 20210 /** 197 20211 * Do either or both things: (1) change the current configuration, and (2) 198 20212 * make sure the given activity is running with the (now) current 199 20213 * configuration. Returns true if the activity has been left running, or 200 20214 * false if <var>starting</var> is being destroyed to match the new 201 20215 * configuration. 202 20216 * 203 20217 * @param userId is only used when persistent parameter is set to true to persist configuration 204 20218 * for that particular user 205 20219 */ 206 20220 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting, 207 20221 boolean initLocale, boolean persistent, int userId, boolean deferResume, 208 20222 UpdateConfigurationResult result) { 209 20223 int changes = 0; 210 20224 boolean kept = true; 211 20225 212 20226 if (mWindowManager != null) { 213 20227 mWindowManager.deferSurfaceLayout(); 214 20228 } 215 20229 try { 216 20230 if (values != null) { 217 20231 changes = updateGlobalConfiguration(values, initLocale, persistent, userId, 218 20232 deferResume); 219 20233 } 220 20234 221 20235 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes); 222 20236 } finally { 223 20237 if (mWindowManager != null) { 224 20238 mWindowManager.continueSurfaceLayout(); 225 20239 } 226 20240 } 227 20241 228 20242 if (result != null) { 229 20243 result.changes = changes; 230 20244 result.activityRelaunched = !kept; 231 20245 } 232 20246 return kept; 233 20247 } 234 20248 235 20249 /** Update default (global) configuration and notify listeners about changes. */ 236 20250 private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale, 237 20251 boolean persistent, int userId, boolean deferResume) { 238 20252 mTempConfig.setTo(getGlobalConfiguration()); 239 20253 final int changes = mTempConfig.updateFrom(values); 240 20254 if (changes == 0) { 241 20255 // Since calling to Activity.setRequestedOrientation leads to freezing the window with 242 20256 // setting WindowManagerService.mWaitingForConfig to true, it is important that we call 243 20257 // performDisplayOverrideConfigUpdate in order to send the new display configuration 244 20258 // (even if there are no actual changes) to unfreeze the window. 245 20259 performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY); 246 20260 return 0; 247 20261 } 248 20262 249 20263 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION, 250 20264 "Updating global configuration to: " + values); 251 20265 252 20266 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 253 20267 254 20268 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) { 255 20269 final LocaleList locales = values.getLocales(); 256 20270 int bestLocaleIndex = 0; 257 20271 if (locales.size() > 1) { 258 20272 if (mSupportedSystemLocales == null) { 259 20273 mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales(); 260 20274 } 261 20275 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales)); 262 20276 } 263 20277 SystemProperties.set("persist.sys.locale", 264 20278 locales.get(bestLocaleIndex).toLanguageTag()); 265 20279 LocaleList.setDefault(locales, bestLocaleIndex); 266 20280 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, 267 20281 locales.get(bestLocaleIndex))); 268 20282 } 269 20283 270 20284 mConfigurationSeq = Math.max(++mConfigurationSeq, 1); 271 20285 mTempConfig.seq = mConfigurationSeq; 272 20286 273 20287 // Update stored global config and notify everyone about the change. 274 20288 mStackSupervisor.onConfigurationChanged(mTempConfig); 275 20289 276 20290 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig); 277 20291 // TODO(multi-display): Update UsageEvents#Event to include displayId. 278 20292 mUsageStatsService.reportConfigurationChange(mTempConfig, 279 20293 mUserController.getCurrentUserIdLocked()); 280 20294 281 20295 // TODO: If our config changes, should we auto dismiss any currently showing dialogs? 282 20296 mShowDialogs = shouldShowDialogs(mTempConfig); 283 20297 284 20298 AttributeCache ac = AttributeCache.instance(); 285 20299 if (ac != null) { 286 20300 ac.updateConfiguration(mTempConfig); 287 20301 } 288 20302 289 20303 // Make sure all resources in our process are updated right now, so that anyone who is going 290 20304 // to retrieve resource values after we return will be sure to get the new ones. This is 291 20305 // especially important during boot, where the first config change needs to guarantee all 292 20306 // resources have that config before following boot code is executed. 293 20307 mSystemThread.applyConfigurationToResources(mTempConfig); 294 20308 295 20309 // We need another copy of global config because we're scheduling some calls instead of 296 20310 // running them in place. We need to be sure that object we send will be handled unchanged. 297 20311 final Configuration configCopy = new Configuration(mTempConfig); 298 20312 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 299 20313 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 300 20314 msg.obj = configCopy; 301 20315 msg.arg1 = userId; 302 20316 mHandler.sendMessage(msg); 303 20317 } 304 20318 305 20319 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 306 20320 ProcessRecord app = mLruProcesses.get(i); 307 20321 try { 308 20322 if (app.thread != null) { 309 20323 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc " 310 20324 + app.processName + " new config " + configCopy); 311 20325 app.thread.scheduleConfigurationChanged(configCopy); 312 20326 } 313 20327 } catch (Exception e) { 314 20328 } 315 20329 } 316 20330 317 20331 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 318 20332 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING 319 20333 | Intent.FLAG_RECEIVER_FOREGROUND 320 20334 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS); 321 20335 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, 322 20336 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID, 323 20337 UserHandle.USER_ALL); 324 20338 if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) { 325 20339 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 326 20340 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND 327 20341 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND 328 20342 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS); 329 20343 if (initLocale || !mProcessesReady) { 330 20344 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 331 20345 } 332 20346 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, 333 20347 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID, 334 20348 UserHandle.USER_ALL); 335 20349 } 336 20350 337 20351 // Override configuration of the default display duplicates global config, so we need to 338 20352 // update it also. This will also notify WindowManager about changes. 339 20353 performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume, 340 20354 DEFAULT_DISPLAY); 341 20355 342 20356 return changes; 343 20357 } 344 20358 345 20359 @Override 346 20360 public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) { 347 20361 enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()"); 348 20362 349 20363 synchronized (this) { 350 20364 // Check if display is initialized in AM. 351 20365 if (!mStackSupervisor.isDisplayAdded(displayId)) { 352 20366 // Call might come when display is not yet added or has already been removed. 353 20367 if (DEBUG_CONFIGURATION) { 354 20368 Slog.w(TAG, "Trying to update display configuration for non-existing displayId=" 355 20369 + displayId); 356 20370 } 357 20371 return false; 358 20372 } 359 20373 360 20374 if (values == null && mWindowManager != null) { 361 20375 // sentinel: fetch the current configuration from the window manager 362 20376 values = mWindowManager.computeNewConfiguration(displayId); 363 20377 } 364 20378 365 20379 if (mWindowManager != null) { 366 20380 // Update OOM levels based on display size. 367 20381 mProcessList.applyDisplaySize(mWindowManager); 368 20382 } 369 20383 370 20384 final long origId = Binder.clearCallingIdentity(); 371 20385 try { 372 20386 if (values != null) { 373 20387 Settings.System.clearConfiguration(values); 374 20388 } 375 20389 updateDisplayOverrideConfigurationLocked(values, null /* starting */, 376 20390 false /* deferResume */, displayId, mTmpUpdateConfigurationResult); 377 20391 return mTmpUpdateConfigurationResult.changes != 0; 378 20392 } finally { 379 20393 Binder.restoreCallingIdentity(origId); 380 20394 } 381 20395 } 382 20396 } 383 20397 384 20398 boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting, 385 20399 boolean deferResume, int displayId) { 386 20400 return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */, 387 20401 displayId, null /* result */); 388 20402 } 389 20403 390 20404 /** 391 20405 * Updates override configuration specific for the selected display. If no config is provided, 392 20406 * new one will be computed in WM based on current display info. 393 20407 */ 394 20408 private boolean updateDisplayOverrideConfigurationLocked(Configuration values, 395 20409 ActivityRecord starting, boolean deferResume, int displayId, 396 20410 UpdateConfigurationResult result) { 397 20411 int changes = 0; 398 20412 boolean kept = true; 399 20413 400 20414 if (mWindowManager != null) { 401 20415 mWindowManager.deferSurfaceLayout(); 402 20416 } 403 20417 try { 404 20418 if (values != null) { 405 20419 if (displayId == DEFAULT_DISPLAY) { 406 20420 // Override configuration of the default display duplicates global config, so 407 20421 // we're calling global config update instead for default display. It will also 408 20422 // apply the correct override config. 409 20423 changes = updateGlobalConfiguration(values, false /* initLocale */, 410 20424 false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume); 411 20425 } else { 412 20426 changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId); 413 20427 } 414 20428 } 415 20429 416 20430 kept = ensureConfigAndVisibilityAfterUpdate(starting, changes); 417 20431 } finally { 418 20432 if (mWindowManager != null) { 419 20433 mWindowManager.continueSurfaceLayout(); 420 20434 } 421 20435 } 422 20436 423 20437 if (result != null) { 424 20438 result.changes = changes; 425 20439 result.activityRelaunched = !kept; 426 20440 } 427 20441 return kept; 428 20442 } 429 20443 430 20444 private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume, 431 20445 int displayId) { 432 20446 mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId)); 433 20447 final int changes = mTempConfig.updateFrom(values); 434 20448 if (changes != 0) { 435 20449 Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " " 436 20450 + mTempConfig + " for displayId=" + displayId); 437 20451 mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId); 438 20452 439 20453 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0; 440 20454 if (isDensityChange && displayId == DEFAULT_DISPLAY) { 441 20455 // Reset the unsupported display size dialog. 442 20456 mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG); 443 20457 444 20458 killAllBackgroundProcessesExcept(N, 445 20459 ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE); 446 20460 } 447 20461 } 448 20462 449 20463 // Update the configuration with WM first and check if any of the stacks need to be resized 450 20464 // due to the configuration change. If so, resize the stacks now and do any relaunches if 451 20465 // necessary. This way we don't need to relaunch again afterwards in 452 20466 // ensureActivityConfigurationLocked(). 453 20467 if (mWindowManager != null) { 454 20468 final int[] resizedStacks = 455 20469 mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId); 456 20470 if (resizedStacks != null) { 457 20471 for (int stackId : resizedStacks) { 458 20472 resizeStackWithBoundsFromWindowManager(stackId, deferResume); 459 20473 } 460 20474 } 461 20475 } 462 20476 463 20477 return changes; 464 20478 } 465 20479 466 20480 /** Applies latest configuration and/or visibility updates if needed. */ 467 20481 private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) { 468 20482 boolean kept = true; 469 20483 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 470 20484 // mainStack is null during startup. 471 20485 if (mainStack != null) { 472 20486 if (changes != 0 && starting == null) { 473 20487 // If the configuration changed, and the caller is not already 474 20488 // in the process of starting an activity, then find the top 475 20489 // activity to check if its configuration needs to change. 476 20490 starting = mainStack.topRunningActivityLocked(); 477 20491 } 478 20492 479 20493 if (starting != null) { 480 20494 kept = starting.ensureActivityConfigurationLocked(changes, 481 20495 false /* preserveWindow */); 482 20496 // And we need to make sure at this point that all other activities 483 20497 // are made visible with the correct configuration. 484 20498 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes, 485 20499 !PRESERVE_WINDOWS); 486 20500 } 487 20501 } 488 20502 489 20503 return kept; 490 20504 } 491 20505 492 20506 /** Helper method that requests bounds from WM and applies them to stack. */ 493 20507 private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) { 494 20508 final Rect newStackBounds = new Rect(); 495 20509 mStackSupervisor.getStack(stackId).getBoundsForNewConfiguration(newStackBounds); 496 20510 mStackSupervisor.resizeStackLocked( 497 20511 stackId, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */, 498 20512 null /* tempTaskBounds */, null /* tempTaskInsetBounds */, 499 20513 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume); 500 20514 } 501 20515 502 20516 /** 503 20517 * Decide based on the configuration whether we should show the ANR, 504 20518 * crash, etc dialogs. The idea is that if there is no affordance to 505 20519 * press the on-screen buttons, or the user experience would be more 506 20520 * greatly impacted than the crash itself, we shouldn't show the dialog. 507 20521 * 508 20522 * A thought: SystemUI might also want to get told about this, the Power 509 20523 * dialog / global actions also might want different behaviors. 510 20524 */ 511 20525 private static boolean shouldShowDialogs(Configuration config) { 512 20526 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS 513 20527 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH 514 20528 && config.navigation == Configuration.NAVIGATION_NONAV); 515 20529 int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK; 516 20530 final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR 517 20531 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE)) 518 20532 && modeType != Configuration.UI_MODE_TYPE_TELEVISION 519 20533 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET); 520 20534 return inputMethodExists && uiModeSupportsDialogs; 521 20535 } 522 20536 523 20537 @Override 524 20538 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 525 20539 synchronized (this) { 526 20540 ActivityRecord srec = ActivityRecord.forTokenLocked(token); 527 20541 if (srec != null) { 528 20542 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity); 529 20543 } 530 20544 } 531 20545 return false; 532 20546 } 533 20547 534 20548 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 535 20549 Intent resultData) { 536 20550 537 20551 synchronized (this) { 538 20552 final ActivityRecord r = ActivityRecord.forTokenLocked(token); 539 20553 if (r != null) { 540 20554 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData); 541 20555 } 542 20556 return false; 543 20557 } 544 20558 } 545 20559 546 20560 public int getLaunchedFromUid(IBinder activityToken) { 547 20561 ActivityRecord srec; 548 20562 synchronized (this) { 549 20563 srec = ActivityRecord.forTokenLocked(activityToken); 550 20564 } 551 20565 if (srec == null) { 552 20566 return -1; 553 20567 } 554 20568 return srec.launchedFromUid; 555 20569 } 556 20570 557 20571 public String getLaunchedFromPackage(IBinder activityToken) { 558 20572 ActivityRecord srec; 559 20573 synchronized (this) { 560 20574 srec = ActivityRecord.forTokenLocked(activityToken); 561 20575 } 562 20576 if (srec == null) { 563 20577 return null; 564 20578 } 565 20579 return srec.launchedFromPackage; 566 20580 } 567 20581
管理app生命周期
1 20582 // ========================================================= 2 20583 // LIFETIME MANAGEMENT 3 20584 // ========================================================= 4 20585 5 20586 // Returns whether the app is receiving broadcast. 6 20587 // If receiving, fetch all broadcast queues which the app is 7 20588 // the current [or imminent] receiver on. 8 20589 private boolean isReceivingBroadcastLocked(ProcessRecord app, 9 20590 ArraySet<BroadcastQueue> receivingQueues) { 10 20591 if (!app.curReceivers.isEmpty()) { 11 20592 for (BroadcastRecord r : app.curReceivers) { 12 20593 receivingQueues.add(r.queue); 13 20594 } 14 20595 return true; 15 20596 } 16 20597 17 20598 // It's not the current receiver, but it might be starting up to become one 18 20599 for (BroadcastQueue queue : mBroadcastQueues) { 19 20600 final BroadcastRecord r = queue.mPendingBroadcast; 20 20601 if (r != null && r.curApp == app) { 21 20602 // found it; report which queue it's in 22 20603 receivingQueues.add(queue); 23 20604 } 24 20605 } 25 20606 26 20607 return !receivingQueues.isEmpty(); 27 20608 } 28 20609 29 20610 Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState, 30 20611 int targetUid, ComponentName targetComponent, String targetProcess) { 31 20612 if (!mTrackingAssociations) { 32 20613 return null; 33 20614 } 34 20615 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components 35 20616 = mAssociations.get(targetUid); 36 20617 if (components == null) { 37 20618 components = new ArrayMap<>(); 38 20619 mAssociations.put(targetUid, components); 39 20620 } 40 20621 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent); 41 20622 if (sourceUids == null) { 42 20623 sourceUids = new SparseArray<>(); 43 20624 components.put(targetComponent, sourceUids); 44 20625 } 45 20626 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid); 46 20627 if (sourceProcesses == null) { 47 20628 sourceProcesses = new ArrayMap<>(); 48 20629 sourceUids.put(sourceUid, sourceProcesses); 49 20630 } 50 20631 Association ass = sourceProcesses.get(sourceProcess); 51 20632 if (ass == null) { 52 20633 ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent, 53 20634 targetProcess); 54 20635 sourceProcesses.put(sourceProcess, ass); 55 20636 } 56 20637 ass.mCount++; 57 20638 ass.mNesting++; 58 20639 if (ass.mNesting == 1) { 59 20640 ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis(); 60 20641 ass.mLastState = sourceState; 61 20642 } 62 20643 return ass; 63 20644 } 64 20645 65 20646 void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid, 66 20647 ComponentName targetComponent) { 67 20648 if (!mTrackingAssociations) { 68 20649 return; 69 20650 } 70 20651 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components 71 20652 = mAssociations.get(targetUid); 72 20653 if (components == null) { 73 20654 return; 74 20655 } 75 20656 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent); 76 20657 if (sourceUids == null) { 77 20658 return; 78 20659 } 79 20660 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid); 80 20661 if (sourceProcesses == null) { 81 20662 return; 82 20663 } 83 20664 Association ass = sourceProcesses.get(sourceProcess); 84 20665 if (ass == null || ass.mNesting <= 0) { 85 20666 return; 86 20667 } 87 20668 ass.mNesting--; 88 20669 if (ass.mNesting == 0) { 89 20670 long uptime = SystemClock.uptimeMillis(); 90 20671 ass.mTime += uptime - ass.mStartTime; 91 20672 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE] 92 20673 += uptime - ass.mLastStateUptime; 93 20674 ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2; 94 20675 } 95 20676 } 96 20677 97 20678 private void noteUidProcessState(final int uid, final int state) { 98 20679 mBatteryStatsService.noteUidProcessState(uid, state); 99 20680 if (mTrackingAssociations) { 100 20681 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) { 101 20682 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents 102 20683 = mAssociations.valueAt(i1); 103 20684 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) { 104 20685 SparseArray<ArrayMap<String, Association>> sourceUids 105 20686 = targetComponents.valueAt(i2); 106 20687 ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid); 107 20688 if (sourceProcesses != null) { 108 20689 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) { 109 20690 Association ass = sourceProcesses.valueAt(i4); 110 20691 if (ass.mNesting >= 1) { 111 20692 // currently associated 112 20693 long uptime = SystemClock.uptimeMillis(); 113 20694 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE] 114 20695 += uptime - ass.mLastStateUptime; 115 20696 ass.mLastState = state; 116 20697 ass.mLastStateUptime = uptime; 117 20698 } 118 20699 } 119 20700 } 120 20701 } 121 20702 } 122 20703 } 123 20704 } 124 20705 125 20706 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 126 20707 boolean doingAll, long now) { 127 20708 if (mAdjSeq == app.adjSeq) { 128 20709 // This adjustment has already been computed. 129 20710 return app.curRawAdj; 130 20711 } 131 20712 132 20713 if (app.thread == null) { 133 20714 app.adjSeq = mAdjSeq; 134 20715 app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND; 135 20716 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 136 20717 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 137 20718 } 138 20719 139 20720 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 140 20721 app.adjSource = null; 141 20722 app.adjTarget = null; 142 20723 app.empty = false; 143 20724 app.cached = false; 144 20725 145 20726 final int activitiesSize = app.activities.size(); 146 20727 147 20728 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 148 20729 // The max adjustment doesn't allow this app to be anything 149 20730 // below foreground, so it is not worth doing work for it. 150 20731 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making fixed: " + app); 151 20732 app.adjType = "fixed"; 152 20733 app.adjSeq = mAdjSeq; 153 20734 app.curRawAdj = app.maxAdj; 154 20735 app.foregroundActivities = false; 155 20736 app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT; 156 20737 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 157 20738 // System processes can do UI, and when they do we want to have 158 20739 // them trim their memory after the user leaves the UI. To 159 20740 // facilitate this, here we need to determine whether or not it 160 20741 // is currently showing UI. 161 20742 app.systemNoUi = true; 162 20743 if (app == TOP_APP) { 163 20744 app.systemNoUi = false; 164 20745 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP; 165 20746 app.adjType = "pers-top-activity"; 166 20747 } else if (app.hasTopUi) { 167 20748 app.systemNoUi = false; 168 20749 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP; 169 20750 app.adjType = "pers-top-ui"; 170 20751 } else if (activitiesSize > 0) { 171 20752 for (int j = 0; j < activitiesSize; j++) { 172 20753 final ActivityRecord r = app.activities.get(j); 173 20754 if (r.visible) { 174 20755 app.systemNoUi = false; 175 20756 } 176 20757 } 177 20758 } 178 20759 if (!app.systemNoUi) { 179 20760 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 180 20761 } 181 20762 return (app.curAdj=app.maxAdj); 182 20763 } 183 20764 184 20765 app.systemNoUi = false; 185 20766 186 20767 final int PROCESS_STATE_CUR_TOP = mTopProcessState; 187 20768 188 20769 // Determine the importance of the process, starting with most 189 20770 // important to least, and assign an appropriate OOM adjustment. 190 20771 int adj; 191 20772 int schedGroup; 192 20773 int procState; 193 20774 boolean foregroundActivities = false; 194 20775 mTmpBroadcastQueue.clear(); 195 20776 if (app == TOP_APP) { 196 20777 // The last app on the list is the foreground app. 197 20778 adj = ProcessList.FOREGROUND_APP_ADJ; 198 20779 schedGroup = ProcessList.SCHED_GROUP_TOP_APP; 199 20780 app.adjType = "top-activity"; 200 20781 foregroundActivities = true; 201 20782 procState = PROCESS_STATE_CUR_TOP; 202 20783 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making top: " + app); 203 20784 } else if (app.instr != null) { 204 20785 // Don't want to kill running instrumentation. 205 20786 adj = ProcessList.FOREGROUND_APP_ADJ; 206 20787 schedGroup = ProcessList.SCHED_GROUP_DEFAULT; 207 20788 app.adjType = "instrumentation"; 208 20789 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE; 209 20790 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making instrumentation: " + app); 210 20791 } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) { 211 20792 // An app that is currently receiving a broadcast also 212 20793 // counts as being in the foreground for OOM killer purposes. 213 20794 // It's placed in a sched group based on the nature of the 214 20795 // broadcast as reflected by which queue it's active in. 215 20796 adj = ProcessList.FOREGROUND_APP_ADJ; 216 20797 schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue)) 217 20798 ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND; 218 20799 app.adjType = "broadcast"; 219 20800 procState = ActivityManager.PROCESS_STATE_RECEIVER; 220 20801 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making broadcast: " + app); 221 20802 } else if (app.executingServices.size() > 0) { 222 20803 // An app that is currently executing a service callback also 223 20804 // counts as being in the foreground. 224 20805 adj = ProcessList.FOREGROUND_APP_ADJ; 225 20806 schedGroup = app.execServicesFg ? 226 20807 ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND; 227 20808 app.adjType = "exec-service"; 228 20809 procState = ActivityManager.PROCESS_STATE_SERVICE; 229 20810 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making exec-service: " + app); 230 20811 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 231 20812 } else { 232 20813 // As far as we know the process is empty. We may change our mind later. 233 20814 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND; 234 20815 // At this point we don't actually know the adjustment. Use the cached adj 235 20816 // value that the caller wants us to. 236 20817 adj = cachedAdj; 237 20818 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 238 20819 app.cached = true; 239 20820 app.empty = true; 240 20821 app.adjType = "cch-empty"; 241 20822 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making empty: " + app); 242 20823 } 243 20824 244 20825 // Examine all activities if not already foreground. 245 20826 if (!foregroundActivities && activitiesSize > 0) { 246 20827 int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX; 247 20828 for (int j = 0; j < activitiesSize; j++) { 248 20829 final ActivityRecord r = app.activities.get(j); 249 20830 if (r.app != app) { 250 20831 Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app 251 20832 + " instead of expected " + app); 252 20833 if (r.app == null || (r.app.uid == app.uid)) { 253 20834 // Only fix things up when they look sane 254 20835 r.app = app; 255 20836 } else { 256 20837 continue; 257 20838 } 258 20839 } 259 20840 if (r.visible) { 260 20841 // App has a visible activity; only upgrade adjustment. 261 20842 if (adj > ProcessList.VISIBLE_APP_ADJ) { 262 20843 adj = ProcessList.VISIBLE_APP_ADJ; 263 20844 app.adjType = "vis-activity"; 264 20845 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app); 265 20846 } 266 20847 if (procState > PROCESS_STATE_CUR_TOP) { 267 20848 procState = PROCESS_STATE_CUR_TOP; 268 20849 app.adjType = "vis-activity"; 269 20850 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app); 270 20851 } 271 20852 schedGroup = ProcessList.SCHED_GROUP_DEFAULT; 272 20853 app.cached = false; 273 20854 app.empty = false; 274 20855 foregroundActivities = true; 275 20856 final TaskRecord task = r.getTask(); 276 20857 if (task != null && minLayer > 0) { 277 20858 final int layer = task.mLayerRank; 278 20859 if (layer >= 0 && minLayer > layer) { 279 20860 minLayer = layer; 280 20861 } 281 20862 } 282 20863 break; 283 20864 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 284 20865 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 285 20866 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 286 20867 app.adjType = "pause-activity"; 287 20868 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app); 288 20869 } 289 20870 if (procState > PROCESS_STATE_CUR_TOP) { 290 20871 procState = PROCESS_STATE_CUR_TOP; 291 20872 app.adjType = "pause-activity"; 292 20873 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app); 293 20874 } 294 20875 schedGroup = ProcessList.SCHED_GROUP_DEFAULT; 295 20876 app.cached = false; 296 20877 app.empty = false; 297 20878 foregroundActivities = true; 298 20879 } else if (r.state == ActivityState.STOPPING) { 299 20880 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 300 20881 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 301 20882 app.adjType = "stop-activity"; 302 20883 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app); 303 20884 } 304 20885 // For the process state, we will at this point consider the 305 20886 // process to be cached. It will be cached either as an activity 306 20887 // or empty depending on whether the activity is finishing. We do 307 20888 // this so that we can treat the process as cached for purposes of 308 20889 // memory trimming (determing current memory level, trim command to 309 20890 // send to process) since there can be an arbitrary number of stopping 310 20891 // processes and they should soon all go into the cached state. 311 20892 if (!r.finishing) { 312 20893 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 313 20894 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 314 20895 app.adjType = "stop-activity"; 315 20896 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app); 316 20897 } 317 20898 } 318 20899 app.cached = false; 319 20900 app.empty = false; 320 20901 foregroundActivities = true; 321 20902 } else { 322 20903 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 323 20904 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 324 20905 app.adjType = "cch-act"; 325 20906 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to cached activity: " + app); 326 20907 } 327 20908 } 328 20909 } 329 20910 if (adj == ProcessList.VISIBLE_APP_ADJ) { 330 20911 adj += minLayer; 331 20912 } 332 20913 } 333 20914 334 20915 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ 335 20916 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) { 336 20917 if (app.foregroundServices) { 337 20918 // The user is aware of this app, so make it visible. 338 20919 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 339 20920 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE; 340 20921 app.cached = false; 341 20922 app.adjType = "fg-service"; 342 20923 schedGroup = ProcessList.SCHED_GROUP_DEFAULT; 343 20924 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to fg service: " + app); 344 20925 } else if (app.hasOverlayUi) { 345 20926 // The process is display an overlay UI. 346 20927 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 347 20928 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 348 20929 app.cached = false; 349 20930 app.adjType = "has-overlay-ui"; 350 20931 schedGroup = ProcessList.SCHED_GROUP_DEFAULT; 351 20932 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to overlay ui: " + app); 352 20933 } 353 20934 } 354 20935 355 20936 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ 356 20937 || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) { 357 20938 if (app.forcingToImportant != null) { 358 20939 // This is currently used for toasts... they are not interactive, and 359 20940 // we don't want them to cause the app to become fully foreground (and 360 20941 // thus out of background check), so we yes the best background level we can. 361 20942 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 362 20943 procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND; 363 20944 app.cached = false; 364 20945 app.adjType = "force-imp"; 365 20946 app.adjSource = app.forcingToImportant; 366 20947 schedGroup = ProcessList.SCHED_GROUP_DEFAULT; 367 20948 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to force imp: " + app); 368 20949 } 369 20950 } 370 20951 371 20952 if (app == mHeavyWeightProcess) { 372 20953 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 373 20954 // We don't want to kill the current heavy-weight process. 374 20955 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 375 20956 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND; 376 20957 app.cached = false; 377 20958 app.adjType = "heavy"; 378 20959 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app); 379 20960 } 380 20961 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 381 20962 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 382 20963 app.adjType = "heavy"; 383 20964 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app); 384 20965 } 385 20966 } 386 20967 387 20968 if (app == mHomeProcess) { 388 20969 if (adj > ProcessList.HOME_APP_ADJ) { 389 20970 // This process is hosting what we currently consider to be the 390 20971 // home app, so we don't want to let it go into the background. 391 20972 adj = ProcessList.HOME_APP_ADJ; 392 20973 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND; 393 20974 app.cached = false; 394 20975 app.adjType = "home"; 395 20976 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app); 396 20977 } 397 20978 if (procState > ActivityManager.PROCESS_STATE_HOME) { 398 20979 procState = ActivityManager.PROCESS_STATE_HOME; 399 20980 app.adjType = "home"; 400 20981 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app); 401 20982 } 402 20983 } 403 20984 404 20985 if (app == mPreviousProcess && app.activities.size() > 0) { 405 20986 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 406 20987 // This was the previous process that showed UI to the user. 407 20988 // We want to try to keep it around more aggressively, to give 408 20989 // a good experience around switching between two apps. 409 20990 adj = ProcessList.PREVIOUS_APP_ADJ; 410 20991 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND; 411 20992 app.cached = false; 412 20993 app.adjType = "previous"; 413 20994 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app); 414 20995 } 415 20996 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 416 20997 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 417 20998 app.adjType = "previous"; 418 20999 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app); 419 21000 } 420 21001 } 421 21002 422 21003 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 423 21004 + " reason=" + app.adjType); 424 21005 425 21006 // By default, we use the computed adjustment. It may be changed if 426 21007 // there are applications dependent on our services or providers, but 427 21008 // this gives us a baseline and makes sure we don't get into an 428 21009 // infinite recursion. 429 21010 app.adjSeq = mAdjSeq; 430 21011 app.curRawAdj = adj; 431 21012 app.hasStartedServices = false; 432 21013 433 21014 if (mBackupTarget != null && app == mBackupTarget.app) { 434 21015 // If possible we want to avoid killing apps while they're being backed up 435 21016 if (adj > ProcessList.BACKUP_APP_ADJ) { 436 21017 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app); 437 21018 adj = ProcessList.BACKUP_APP_ADJ; 438 21019 if (procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) { 439 21020 procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND; 440 21021 } 441 21022 app.adjType = "backup"; 442 21023 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app); 443 21024 app.cached = false; 444 21025 } 445 21026 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 446 21027 procState = ActivityManager.PROCESS_STATE_BACKUP; 447 21028 app.adjType = "backup"; 448 21029 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app); 449 21030 } 450 21031 } 451 21032 452 21033 boolean mayBeTop = false; 453 21034 String mayBeTopType = null; 454 21035 Object mayBeTopSource = null; 455 21036 Object mayBeTopTarget = null; 456 21037 457 21038 for (int is = app.services.size()-1; 458 21039 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 459 21040 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND 460 21041 || procState > ActivityManager.PROCESS_STATE_TOP); 461 21042 is--) { 462 21043 ServiceRecord s = app.services.valueAt(is); 463 21044 if (s.startRequested) { 464 21045 app.hasStartedServices = true; 465 21046 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 466 21047 procState = ActivityManager.PROCESS_STATE_SERVICE; 467 21048 app.adjType = "started-services"; 468 21049 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app); 469 21050 } 470 21051 if (app.hasShownUi && app != mHomeProcess) { 471 21052 // If this process has shown some UI, let it immediately 472 21053 // go to the LRU list because it may be pretty heavy with 473 21054 // UI stuff. We'll tag it with a label just to help 474 21055 // debug and understand what is going on. 475 21056 if (adj > ProcessList.SERVICE_ADJ) { 476 21057 app.adjType = "cch-started-ui-services"; 477 21058 } 478 21059 } else { 479 21060 if (now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) { 480 21061 // This service has seen some activity within 481 21062 // recent memory, so we will keep its process ahead 482 21063 // of the background processes. 483 21064 if (adj > ProcessList.SERVICE_ADJ) { 484 21065 adj = ProcessList.SERVICE_ADJ; 485 21066 app.adjType = "started-services"; 486 21067 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app); 487 21068 app.cached = false; 488 21069 } 489 21070 } 490 21071 // If we have let the service slide into the background 491 21072 // state, still have some text describing what it is doing 492 21073 // even though the service no longer has an impact. 493 21074 if (adj > ProcessList.SERVICE_ADJ) { 494 21075 app.adjType = "cch-started-services"; 495 21076 } 496 21077 } 497 21078 } 498 21079 499 21080 for (int conni = s.connections.size()-1; 500 21081 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 501 21082 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND 502 21083 || procState > ActivityManager.PROCESS_STATE_TOP); 503 21084 conni--) { 504 21085 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 505 21086 for (int i = 0; 506 21087 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 507 21088 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND 508 21089 || procState > ActivityManager.PROCESS_STATE_TOP); 509 21090 i++) { 510 21091 // XXX should compute this based on the max of 511 21092 // all connected clients. 512 21093 ConnectionRecord cr = clist.get(i); 513 21094 if (cr.binding.client == app) { 514 21095 // Binding to ourself is not interesting. 515 21096 continue; 516 21097 } 517 21098 518 21099 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 519 21100 ProcessRecord client = cr.binding.client; 520 21101 int clientAdj = computeOomAdjLocked(client, cachedAdj, 521 21102 TOP_APP, doingAll, now); 522 21103 int clientProcState = client.curProcState; 523 21104 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 524 21105 // If the other app is cached for any reason, for purposes here 525 21106 // we are going to consider it empty. The specific cached state 526 21107 // doesn't propagate except under certain conditions. 527 21108 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 528 21109 } 529 21110 String adjType = null; 530 21111 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 531 21112 // Not doing bind OOM management, so treat 532 21113 // this guy more like a started service. 533 21114 if (app.hasShownUi && app != mHomeProcess) { 534 21115 // If this process has shown some UI, let it immediately 535 21116 // go to the LRU list because it may be pretty heavy with 536 21117 // UI stuff. We'll tag it with a label just to help 537 21118 // debug and understand what is going on. 538 21119 if (adj > clientAdj) { 539 21120 adjType = "cch-bound-ui-services"; 540 21121 } 541 21122 app.cached = false; 542 21123 clientAdj = adj; 543 21124 clientProcState = procState; 544 21125 } else { 545 21126 if (now >= (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) { 546 21127 // This service has not seen activity within 547 21128 // recent memory, so allow it to drop to the 548 21129 // LRU list if there is no other reason to keep 549 21130 // it around. We'll also tag it with a label just 550 21131 // to help debug and undertand what is going on. 551 21132 if (adj > clientAdj) { 552 21133 adjType = "cch-bound-services"; 553 21134 } 554 21135 clientAdj = adj; 555 21136 } 556 21137 } 557 21138 } 558 21139 if (adj > clientAdj) { 559 21140 // If this process has recently shown UI, and 560 21141 // the process that is binding to it is less 561 21142 // important than being visible, then we don't 562 21143 // care about the binding as much as we care 563 21144 // about letting this process get into the LRU 564 21145 // list to be killed and restarted if needed for 565 21146 // memory. 566 21147 if (app.hasShownUi && app != mHomeProcess 567 21148 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 568 21149 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 569 21150 adjType = "cch-bound-ui-services"; 570 21151 } 571 21152 } else { 572 21153 int newAdj; 573 21154 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 574 21155 |Context.BIND_IMPORTANT)) != 0) { 575 21156 newAdj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ 576 21157 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ; 577 21158 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 578 21159 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 579 21160 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 580 21161 newAdj = ProcessList.PERCEPTIBLE_APP_ADJ; 581 21162 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 582 21163 newAdj = clientAdj; 583 21164 } else { 584 21165 if (adj > ProcessList.VISIBLE_APP_ADJ) { 585 21166 newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ); 586 21167 } else { 587 21168 newAdj = adj; 588 21169 } 589 21170 } 590 21171 if (!client.cached) { 591 21172 app.cached = false; 592 21173 } 593 21174 if (adj > newAdj) { 594 21175 adj = newAdj; 595 21176 adjType = "service"; 596 21177 } 597 21178 } 598 21179 } 599 21180 if ((cr.flags & (Context.BIND_NOT_FOREGROUND 600 21181 | Context.BIND_IMPORTANT_BACKGROUND)) == 0) { 601 21182 // This will treat important bound services identically to 602 21183 // the top app, which may behave differently than generic 603 21184 // foreground work. 604 21185 if (client.curSchedGroup > schedGroup) { 605 21186 if ((cr.flags&Context.BIND_IMPORTANT) != 0) { 606 21187 schedGroup = client.curSchedGroup; 607 21188 } else { 608 21189 schedGroup = ProcessList.SCHED_GROUP_DEFAULT; 609 21190 } 610 21191 } 611 21192 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 612 21193 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 613 21194 // Special handling of clients who are in the top state. 614 21195 // We *may* want to consider this process to be in the 615 21196 // top state as well, but only if there is not another 616 21197 // reason for it to be running. Being on the top is a 617 21198 // special state, meaning you are specifically running 618 21199 // for the current top app. If the process is already 619 21200 // running in the background for some other reason, it 620 21201 // is more important to continue considering it to be 621 21202 // in the background state. 622 21203 mayBeTop = true; 623 21204 mayBeTopType = "service"; 624 21205 mayBeTopSource = cr.binding.client; 625 21206 mayBeTopTarget = s.name; 626 21207 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 627 21208 } else { 628 21209 // Special handling for above-top states (persistent 629 21210 // processes). These should not bring the current process 630 21211 // into the top state, since they are not on top. Instead 631 21212 // give them the best state after that. 632 21213 if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) { 633 21214 clientProcState = 634 21215 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE; 635 21216 } else if (mWakefulness 636 21217 == PowerManagerInternal.WAKEFULNESS_AWAKE && 637 21218 (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE) 638 21219 != 0) { 639 21220 clientProcState = 640 21221 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE; 641 21222 } else { 642 21223 clientProcState = 643 21224 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 644 21225 } 645 21226 } 646 21227 } 647 21228 } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) { 648 21229 if (clientProcState < 649 21230 ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) { 650 21231 clientProcState = 651 21232 ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND; 652 21233 } 653 21234 } else { 654 21235 if (clientProcState < 655 21236 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 656 21237 clientProcState = 657 21238 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 658 21239 } 659 21240 } 660 21241 if (procState > clientProcState) { 661 21242 procState = clientProcState; 662 21243 if (adjType == null) { 663 21244 adjType = "service"; 664 21245 } 665 21246 } 666 21247 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 667 21248 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 668 21249 app.pendingUiClean = true; 669 21250 } 670 21251 if (adjType != null) { 671 21252 app.adjType = adjType; 672 21253 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 673 21254 .REASON_SERVICE_IN_USE; 674 21255 app.adjSource = cr.binding.client; 675 21256 app.adjSourceProcState = clientProcState; 676 21257 app.adjTarget = s.name; 677 21258 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType 678 21259 + ": " + app + ", due to " + cr.binding.client 679 21260 + " adj=" + adj + " procState=" + procState); 680 21261 } 681 21262 } 682 21263 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 683 21264 app.treatLikeActivity = true; 684 21265 } 685 21266 final ActivityRecord a = cr.activity; 686 21267 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 687 21268 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 688 21269 (a.visible || a.state == ActivityState.RESUMED || 689 21270 a.state == ActivityState.PAUSING)) { 690 21271 adj = ProcessList.FOREGROUND_APP_ADJ; 691 21272 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 692 21273 if ((cr.flags&Context.BIND_IMPORTANT) != 0) { 693 21274 schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND; 694 21275 } else { 695 21276 schedGroup = ProcessList.SCHED_GROUP_DEFAULT; 696 21277 } 697 21278 } 698 21279 app.cached = false; 699 21280 app.adjType = "service"; 700 21281 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 701 21282 .REASON_SERVICE_IN_USE; 702 21283 app.adjSource = a; 703 21284 app.adjSourceProcState = procState; 704 21285 app.adjTarget = s.name; 705 21286 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to service w/activity: " 706 21287 + app); 707 21288 } 708 21289 } 709 21290 } 710 21291 } 711 21292 } 712 21293 713 21294 for (int provi = app.pubProviders.size()-1; 714 21295 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 715 21296 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND 716 21297 || procState > ActivityManager.PROCESS_STATE_TOP); 717 21298 provi--) { 718 21299 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 719 21300 for (int i = cpr.connections.size()-1; 720 21301 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 721 21302 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND 722 21303 || procState > ActivityManager.PROCESS_STATE_TOP); 723 21304 i--) { 724 21305 ContentProviderConnection conn = cpr.connections.get(i); 725 21306 ProcessRecord client = conn.client; 726 21307 if (client == app) { 727 21308 // Being our own client is not interesting. 728 21309 continue; 729 21310 } 730 21311 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 731 21312 int clientProcState = client.curProcState; 732 21313 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 733 21314 // If the other app is cached for any reason, for purposes here 734 21315 // we are going to consider it empty. 735 21316 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 736 21317 } 737 21318 String adjType = null; 738 21319 if (adj > clientAdj) { 739 21320 if (app.hasShownUi && app != mHomeProcess 740 21321 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 741 21322 adjType = "cch-ui-provider"; 742 21323 } else { 743 21324 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 744 21325 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 745 21326 adjType = "provider"; 746 21327 } 747 21328 app.cached &= client.cached; 748 21329 } 749 21330 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 750 21331 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 751 21332 // Special handling of clients who are in the top state. 752 21333 // We *may* want to consider this process to be in the 753 21334 // top state as well, but only if there is not another 754 21335 // reason for it to be running. Being on the top is a 755 21336 // special state, meaning you are specifically running 756 21337 // for the current top app. If the process is already 757 21338 // running in the background for some other reason, it 758 21339 // is more important to continue considering it to be 759 21340 // in the background state. 760 21341 mayBeTop = true; 761 21342 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 762 21343 mayBeTopType = adjType = "provider-top"; 763 21344 mayBeTopSource = client; 764 21345 mayBeTopTarget = cpr.name; 765 21346 } else { 766 21347 // Special handling for above-top states (persistent 767 21348 // processes). These should not bring the current process 768 21349 // into the top state, since they are not on top. Instead 769 21350 // give them the best state after that. 770 21351 clientProcState = 771 21352 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE; 772 21353 if (adjType == null) { 773 21354 adjType = "provider"; 774 21355 } 775 21356 } 776 21357 } 777 21358 if (procState > clientProcState) { 778 21359 procState = clientProcState; 779 21360 } 780 21361 if (client.curSchedGroup > schedGroup) { 781 21362 schedGroup = ProcessList.SCHED_GROUP_DEFAULT; 782 21363 } 783 21364 if (adjType != null) { 784 21365 app.adjType = adjType; 785 21366 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 786 21367 .REASON_PROVIDER_IN_USE; 787 21368 app.adjSource = client; 788 21369 app.adjSourceProcState = clientProcState; 789 21370 app.adjTarget = cpr.name; 790 21371 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType 791 21372 + ": " + app + ", due to " + client 792 21373 + " adj=" + adj + " procState=" + procState); 793 21374 } 794 21375 } 795 21376 // If the provider has external (non-framework) process 796 21377 // dependencies, ensure that its adjustment is at least 797 21378 // FOREGROUND_APP_ADJ. 798 21379 if (cpr.hasExternalProcessHandles()) { 799 21380 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 800 21381 adj = ProcessList.FOREGROUND_APP_ADJ; 801 21382 schedGroup = ProcessList.SCHED_GROUP_DEFAULT; 802 21383 app.cached = false; 803 21384 app.adjType = "ext-provider"; 804 21385 app.adjTarget = cpr.name; 805 21386 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to external provider: " + app); 806 21387 } 807 21388 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 808 21389 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 809 21390 } 810 21391 } 811 21392 } 812 21393 813 21394 if (app.lastProviderTime > 0 && 814 21395 (app.lastProviderTime+mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) { 815 21396 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 816 21397 adj = ProcessList.PREVIOUS_APP_ADJ; 817 21398 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND; 818 21399 app.cached = false; 819 21400 app.adjType = "recent-provider"; 820 21401 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app); 821 21402 } 822 21403 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 823 21404 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 824 21405 app.adjType = "recent-provider"; 825 21406 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app); 826 21407 } 827 21408 } 828 21409 829 21410 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 830 21411 // A client of one of our services or providers is in the top state. We 831 21412 // *may* want to be in the top state, but not if we are already running in 832 21413 // the background for some other reason. For the decision here, we are going 833 21414 // to pick out a few specific states that we want to remain in when a client 834 21415 // is top (states that tend to be longer-term) and otherwise allow it to go 835 21416 // to the top state. 836 21417 switch (procState) { 837 21418 case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE: 838 21419 // Something else is keeping it at this level, just leave it. 839 21420 break; 840 21421 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 841 21422 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 842 21423 case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND: 843 21424 case ActivityManager.PROCESS_STATE_SERVICE: 844 21425 // These all are longer-term states, so pull them up to the top 845 21426 // of the background states, but not all the way to the top state. 846 21427 procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE; 847 21428 app.adjType = mayBeTopType; 848 21429 app.adjSource = mayBeTopSource; 849 21430 app.adjTarget = mayBeTopTarget; 850 21431 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType 851 21432 + ": " + app + ", due to " + mayBeTopSource 852 21433 + " adj=" + adj + " procState=" + procState); 853 21434 break; 854 21435 default: 855 21436 // Otherwise, top is a better choice, so take it. 856 21437 procState = ActivityManager.PROCESS_STATE_TOP; 857 21438 app.adjType = mayBeTopType; 858 21439 app.adjSource = mayBeTopSource; 859 21440 app.adjTarget = mayBeTopTarget; 860 21441 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType 861 21442 + ": " + app + ", due to " + mayBeTopSource 862 21443 + " adj=" + adj + " procState=" + procState); 863 21444 break; 864 21445 } 865 21446 } 866 21447 867 21448 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 868 21449 if (app.hasClientActivities) { 869 21450 // This is a cached process, but with client activities. Mark it so. 870 21451 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 871 21452 app.adjType = "cch-client-act"; 872 21453 } else if (app.treatLikeActivity) { 873 21454 // This is a cached process, but somebody wants us to treat it like it has 874 21455 // an activity, okay! 875 21456 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 876 21457 app.adjType = "cch-as-act"; 877 21458 } 878 21459 } 879 21460 880 21461 if (adj == ProcessList.SERVICE_ADJ) { 881 21462 if (doingAll) { 882 21463 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 883 21464 mNewNumServiceProcs++; 884 21465 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 885 21466 if (!app.serviceb) { 886 21467 // This service isn't far enough down on the LRU list to 887 21468 // normally be a B service, but if we are low on RAM and it 888 21469 // is large we want to force it down since we would prefer to 889 21470 // keep launcher over it. 890 21471 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 891 21472 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 892 21473 app.serviceHighRam = true; 893 21474 app.serviceb = true; 894 21475 //Slog.i(TAG, "ADJ " + app + " high ram!"); 895 21476 } else { 896 21477 mNewNumAServiceProcs++; 897 21478 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 898 21479 } 899 21480 } else { 900 21481 app.serviceHighRam = false; 901 21482 } 902 21483 } 903 21484 if (app.serviceb) { 904 21485 adj = ProcessList.SERVICE_B_ADJ; 905 21486 } 906 21487 } 907 21488 908 21489 app.curRawAdj = adj; 909 21490 910 21491 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 911 21492 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 912 21493 if (adj > app.maxAdj) { 913 21494 adj = app.maxAdj; 914 21495 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 915 21496 schedGroup = ProcessList.SCHED_GROUP_DEFAULT; 916 21497 } 917 21498 } 918 21499 919 21500 // Do final modification to adj. Everything we do between here and applying 920 21501 // the final setAdj must be done in this function, because we will also use 921 21502 // it when computing the final cached adj later. Note that we don't need to 922 21503 // worry about this for max adj above, since max adj will always be used to 923 21504 // keep it out of the cached vaues. 924 21505 app.curAdj = app.modifyRawOomAdj(adj); 925 21506 app.curSchedGroup = schedGroup; 926 21507 app.curProcState = procState; 927 21508 app.foregroundActivities = foregroundActivities; 928 21509 929 21510 return app.curRawAdj; 930 21511 } 931 21512 932 21513 /** 933 21514 * Record new PSS sample for a process. 934 21515 */ 935 21516 void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss, 936 21517 long now) { 937 21518 EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024, 938 21519 swapPss * 1024); 939 21520 proc.lastPssTime = now; 940 21521 proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList); 941 21522 if (DEBUG_PSS) Slog.d(TAG_PSS, 942 21523 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss 943 21524 + " state=" + ProcessList.makeProcStateString(procState)); 944 21525 if (proc.initialIdlePss == 0) { 945 21526 proc.initialIdlePss = pss; 946 21527 } 947 21528 proc.lastPss = pss; 948 21529 proc.lastSwapPss = swapPss; 949 21530 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 950 21531 proc.lastCachedPss = pss; 951 21532 proc.lastCachedSwapPss = swapPss; 952 21533 } 953 21534 954 21535 final SparseArray<Pair<Long, String>> watchUids 955 21536 = mMemWatchProcesses.getMap().get(proc.processName); 956 21537 Long check = null; 957 21538 if (watchUids != null) { 958 21539 Pair<Long, String> val = watchUids.get(proc.uid); 959 21540 if (val == null) { 960 21541 val = watchUids.get(0); 961 21542 } 962 21543 if (val != null) { 963 21544 check = val.first; 964 21545 } 965 21546 } 966 21547 if (check != null) { 967 21548 if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) { 968 21549 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 969 21550 if (!isDebuggable) { 970 21551 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 971 21552 isDebuggable = true; 972 21553 } 973 21554 } 974 21555 if (isDebuggable) { 975 21556 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting"); 976 21557 final ProcessRecord myProc = proc; 977 21558 final File heapdumpFile = DumpHeapProvider.getJavaFile(); 978 21559 mMemWatchDumpProcName = proc.processName; 979 21560 mMemWatchDumpFile = heapdumpFile.toString(); 980 21561 mMemWatchDumpPid = proc.pid; 981 21562 mMemWatchDumpUid = proc.uid; 982 21563 BackgroundThread.getHandler().post(new Runnable() { 983 21564 @Override 984 21565 public void run() { 985 21566 revokeUriPermission(ActivityThread.currentActivityThread() 986 21567 .getApplicationThread(), 987 21568 null, DumpHeapActivity.JAVA_URI, 988 21569 Intent.FLAG_GRANT_READ_URI_PERMISSION 989 21570 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION, 990 21571 UserHandle.myUserId()); 991 21572 ParcelFileDescriptor fd = null; 992 21573 try { 993 21574 heapdumpFile.delete(); 994 21575 fd = ParcelFileDescriptor.open(heapdumpFile, 995 21576 ParcelFileDescriptor.MODE_CREATE | 996 21577 ParcelFileDescriptor.MODE_TRUNCATE | 997 21578 ParcelFileDescriptor.MODE_WRITE_ONLY | 998 21579 ParcelFileDescriptor.MODE_APPEND); 999 21580 IApplicationThread thread = myProc.thread; 1000 21581 if (thread != null) { 1001 21582 try { 1002 21583 if (DEBUG_PSS) Slog.d(TAG_PSS, 1003 21584 "Requesting dump heap from " 1004 21585 + myProc + " to " + heapdumpFile); 1005 21586 thread.dumpHeap(true, heapdumpFile.toString(), fd); 1006 21587 } catch (RemoteException e) { 1007 21588 } 1008 21589 } 1009 21590 } catch (FileNotFoundException e) { 1010 21591 e.printStackTrace(); 1011 21592 } finally { 1012 21593 if (fd != null) { 1013 21594 try { 1014 21595 fd.close(); 1015 21596 } catch (IOException e) { 1016 21597 } 1017 21598 } 1018 21599 } 1019 21600 } 1020 21601 }); 1021 21602 } else { 1022 21603 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check 1023 21604 + ", but debugging not enabled"); 1024 21605 } 1025 21606 } 1026 21607 } 1027 21608 } 1028 21609 1029 21610 /** 1030 21611 * Schedule PSS collection of a process. 1031 21612 */ 1032 21613 void requestPssLocked(ProcessRecord proc, int procState) { 1033 21614 if (mPendingPssProcesses.contains(proc)) { 1034 21615 return; 1035 21616 } 1036 21617 if (mPendingPssProcesses.size() == 0) { 1037 21618 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 1038 21619 } 1039 21620 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc); 1040 21621 proc.pssProcState = procState; 1041 21622 mPendingPssProcesses.add(proc); 1042 21623 } 1043 21624 1044 21625 /** 1045 21626 * Schedule PSS collection of all processes. 1046 21627 */ 1047 21628 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 1048 21629 if (!always) { 1049 21630 if (now < (mLastFullPssTime + 1050 21631 (memLowered ? mConstants.FULL_PSS_LOWERED_INTERVAL 1051 21632 : mConstants.FULL_PSS_MIN_INTERVAL))) { 1052 21633 return; 1053 21634 } 1054 21635 } 1055 21636 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs! memLowered=" + memLowered); 1056 21637 mLastFullPssTime = now; 1057 21638 mFullPssPending = true; 1058 21639 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 1059 21640 mPendingPssProcesses.clear(); 1060 21641 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 1061 21642 ProcessRecord app = mLruProcesses.get(i); 1062 21643 if (app.thread == null 1063 21644 || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) { 1064 21645 continue; 1065 21646 } 1066 21647 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 1067 21648 app.pssProcState = app.setProcState; 1068 21649 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 1069 21650 mTestPssMode, isSleepingLocked(), now); 1070 21651 mPendingPssProcesses.add(app); 1071 21652 } 1072 21653 } 1073 21654 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 1074 21655 } 1075 21656 1076 21657 public void setTestPssMode(boolean enabled) { 1077 21658 synchronized (this) { 1078 21659 mTestPssMode = enabled; 1079 21660 if (enabled) { 1080 21661 // Whenever we enable the mode, we want to take a snapshot all of current 1081 21662 // process mem use. 1082 21663 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true); 1083 21664 } 1084 21665 } 1085 21666 } 1086 21667 1087 21668 /** 1088 21669 * Ask a given process to GC right now. 1089 21670 */ 1090 21671 final void performAppGcLocked(ProcessRecord app) { 1091 21672 try { 1092 21673 app.lastRequestedGc = SystemClock.uptimeMillis(); 1093 21674 if (app.thread != null) { 1094 21675 if (app.reportLowMemory) { 1095 21676 app.reportLowMemory = false; 1096 21677 app.thread.scheduleLowMemory(); 1097 21678 } else { 1098 21679 app.thread.processInBackground(); 1099 21680 } 1100 21681 } 1101 21682 } catch (Exception e) { 1102 21683 // whatever. 1103 21684 } 1104 21685 } 1105 21686 1106 21687 /** 1107 21688 * Returns true if things are idle enough to perform GCs. 1108 21689 */ 1109 21690 private final boolean canGcNowLocked() { 1110 21691 boolean processingBroadcasts = false; 1111 21692 for (BroadcastQueue q : mBroadcastQueues) { 1112 21693 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 1113 21694 processingBroadcasts = true; 1114 21695 } 1115 21696 } 1116 21697 return !processingBroadcasts 1117 21698 && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle()); 1118 21699 } 1119 21700 1120 21701 /** 1121 21702 * Perform GCs on all processes that are waiting for it, but only 1122 21703 * if things are idle. 1123 21704 */ 1124 21705 final void performAppGcsLocked() { 1125 21706 final int N = mProcessesToGc.size(); 1126 21707 if (N <= 0) { 1127 21708 return; 1128 21709 } 1129 21710 if (canGcNowLocked()) { 1130 21711 while (mProcessesToGc.size() > 0) { 1131 21712 ProcessRecord proc = mProcessesToGc.remove(0); 1132 21713 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 1133 21714 if ((proc.lastRequestedGc+mConstants.GC_MIN_INTERVAL) 1134 21715 <= SystemClock.uptimeMillis()) { 1135 21716 // To avoid spamming the system, we will GC processes one 1136 21717 // at a time, waiting a few seconds between each. 1137 21718 performAppGcLocked(proc); 1138 21719 scheduleAppGcsLocked(); 1139 21720 return; 1140 21721 } else { 1141 21722 // It hasn't been long enough since we last GCed this 1142 21723 // process... put it in the list to wait for its time. 1143 21724 addProcessToGcListLocked(proc); 1144 21725 break; 1145 21726 } 1146 21727 } 1147 21728 } 1148 21729 1149 21730 scheduleAppGcsLocked(); 1150 21731 } 1151 21732 } 1152 21733 1153 21734 /** 1154 21735 * If all looks good, perform GCs on all processes waiting for them. 1155 21736 */ 1156 21737 final void performAppGcsIfAppropriateLocked() { 1157 21738 if (canGcNowLocked()) { 1158 21739 performAppGcsLocked(); 1159 21740 return; 1160 21741 } 1161 21742 // Still not idle, wait some more. 1162 21743 scheduleAppGcsLocked(); 1163 21744 } 1164 21745 1165 21746 /** 1166 21747 * Schedule the execution of all pending app GCs. 1167 21748 */ 1168 21749 final void scheduleAppGcsLocked() { 1169 21750 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 1170 21751 1171 21752 if (mProcessesToGc.size() > 0) { 1172 21753 // Schedule a GC for the time to the next process. 1173 21754 ProcessRecord proc = mProcessesToGc.get(0); 1174 21755 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 1175 21756 1176 21757 long when = proc.lastRequestedGc + mConstants.GC_MIN_INTERVAL; 1177 21758 long now = SystemClock.uptimeMillis(); 1178 21759 if (when < (now+mConstants.GC_TIMEOUT)) { 1179 21760 when = now + mConstants.GC_TIMEOUT; 1180 21761 } 1181 21762 mHandler.sendMessageAtTime(msg, when); 1182 21763 } 1183 21764 } 1184 21765 1185 21766 /** 1186 21767 * Add a process to the array of processes waiting to be GCed. Keeps the 1187 21768 * list in sorted order by the last GC time. The process can't already be 1188 21769 * on the list. 1189 21770 */ 1190 21771 final void addProcessToGcListLocked(ProcessRecord proc) { 1191 21772 boolean added = false; 1192 21773 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 1193 21774 if (mProcessesToGc.get(i).lastRequestedGc < 1194 21775 proc.lastRequestedGc) { 1195 21776 added = true; 1196 21777 mProcessesToGc.add(i+1, proc); 1197 21778 break; 1198 21779 } 1199 21780 } 1200 21781 if (!added) { 1201 21782 mProcessesToGc.add(0, proc); 1202 21783 } 1203 21784 } 1204 21785 1205 21786 /** 1206 21787 * Set up to ask a process to GC itself. This will either do it 1207 21788 * immediately, or put it on the list of processes to gc the next 1208 21789 * time things are idle. 1209 21790 */ 1210 21791 final void scheduleAppGcLocked(ProcessRecord app) { 1211 21792 long now = SystemClock.uptimeMillis(); 1212 21793 if ((app.lastRequestedGc+mConstants.GC_MIN_INTERVAL) > now) { 1213 21794 return; 1214 21795 } 1215 21796 if (!mProcessesToGc.contains(app)) { 1216 21797 addProcessToGcListLocked(app); 1217 21798 scheduleAppGcsLocked(); 1218 21799 } 1219 21800 } 1220 21801 1221 21802 final void checkExcessivePowerUsageLocked(boolean doKills) { 1222 21803 updateCpuStatsNow(); 1223 21804 1224 21805 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 1225 21806 boolean doWakeKills = doKills; 1226 21807 boolean doCpuKills = doKills; 1227 21808 if (mLastPowerCheckRealtime == 0) { 1228 21809 doWakeKills = false; 1229 21810 } 1230 21811 if (mLastPowerCheckUptime == 0) { 1231 21812 doCpuKills = false; 1232 21813 } 1233 21814 if (stats.isScreenOn()) { 1234 21815 doWakeKills = false; 1235 21816 } 1236 21817 final long curRealtime = SystemClock.elapsedRealtime(); 1237 21818 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 1238 21819 final long curUptime = SystemClock.uptimeMillis(); 1239 21820 final long uptimeSince = curUptime - mLastPowerCheckUptime; 1240 21821 mLastPowerCheckRealtime = curRealtime; 1241 21822 mLastPowerCheckUptime = curUptime; 1242 21823 if (realtimeSince < mConstants.WAKE_LOCK_MIN_CHECK_DURATION) { 1243 21824 doWakeKills = false; 1244 21825 } 1245 21826 if (uptimeSince < mConstants.CPU_MIN_CHECK_DURATION) { 1246 21827 doCpuKills = false; 1247 21828 } 1248 21829 int i = mLruProcesses.size(); 1249 21830 while (i > 0) { 1250 21831 i--; 1251 21832 ProcessRecord app = mLruProcesses.get(i); 1252 21833 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 1253 21834 long wtime; 1254 21835 synchronized (stats) { 1255 21836 wtime = stats.getProcessWakeTime(app.info.uid, 1256 21837 app.pid, curRealtime); 1257 21838 } 1258 21839 long wtimeUsed = wtime - app.lastWakeTime; 1259 21840 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 1260 21841 if (DEBUG_POWER) { 1261 21842 StringBuilder sb = new StringBuilder(128); 1262 21843 sb.append("Wake for "); 1263 21844 app.toShortString(sb); 1264 21845 sb.append(": over "); 1265 21846 TimeUtils.formatDuration(realtimeSince, sb); 1266 21847 sb.append(" used "); 1267 21848 TimeUtils.formatDuration(wtimeUsed, sb); 1268 21849 sb.append(" ("); 1269 21850 sb.append((wtimeUsed*100)/realtimeSince); 1270 21851 sb.append("%)"); 1271 21852 Slog.i(TAG_POWER, sb.toString()); 1272 21853 sb.setLength(0); 1273 21854 sb.append("CPU for "); 1274 21855 app.toShortString(sb); 1275 21856 sb.append(": over "); 1276 21857 TimeUtils.formatDuration(uptimeSince, sb); 1277 21858 sb.append(" used "); 1278 21859 TimeUtils.formatDuration(cputimeUsed, sb); 1279 21860 sb.append(" ("); 1280 21861 sb.append((cputimeUsed*100)/uptimeSince); 1281 21862 sb.append("%)"); 1282 21863 Slog.i(TAG_POWER, sb.toString()); 1283 21864 } 1284 21865 // If a process has held a wake lock for more 1285 21866 // than 50% of the time during this period, 1286 21867 // that sounds bad. Kill! 1287 21868 if (doWakeKills && realtimeSince > 0 1288 21869 && ((wtimeUsed*100)/realtimeSince) >= 50) { 1289 21870 synchronized (stats) { 1290 21871 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 1291 21872 realtimeSince, wtimeUsed); 1292 21873 } 1293 21874 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 1294 21875 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 1295 21876 } else if (doCpuKills && uptimeSince > 0 1296 21877 && ((cputimeUsed*100)/uptimeSince) >= 25) { 1297 21878 synchronized (stats) { 1298 21879 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 1299 21880 uptimeSince, cputimeUsed); 1300 21881 } 1301 21882 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 1302 21883 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 1303 21884 } else { 1304 21885 app.lastWakeTime = wtime; 1305 21886 app.lastCpuTime = app.curCpuTime; 1306 21887 } 1307 21888 } 1308 21889 } 1309 21890 } 1310 21891 1311 21892 private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now, 1312 21893 long nowElapsed) { 1313 21894 boolean success = true; 1314 21895 1315 21896 if (app.curRawAdj != app.setRawAdj) { 1316 21897 app.setRawAdj = app.curRawAdj; 1317 21898 } 1318 21899 1319 21900 int changes = 0; 1320 21901 1321 21902 if (app.curAdj != app.setAdj) { 1322 21903 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 1323 21904 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ, 1324 21905 "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": " 1325 21906 + app.adjType); 1326 21907 app.setAdj = app.curAdj; 1327 21908 app.verifiedAdj = ProcessList.INVALID_ADJ; 1328 21909 } 1329 21910 1330 21911 if (app.setSchedGroup != app.curSchedGroup) { 1331 21912 int oldSchedGroup = app.setSchedGroup; 1332 21913 app.setSchedGroup = app.curSchedGroup; 1333 21914 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ, 1334 21915 "Setting sched group of " + app.processName 1335 21916 + " to " + app.curSchedGroup); 1336 21917 if (app.waitingToKill != null && app.curReceivers.isEmpty() 1337 21918 && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) { 1338 21919 app.kill(app.waitingToKill, true); 1339 21920 success = false; 1340 21921 } else { 1341 21922 int processGroup; 1342 21923 switch (app.curSchedGroup) { 1343 21924 case ProcessList.SCHED_GROUP_BACKGROUND: 1344 21925 processGroup = THREAD_GROUP_BG_NONINTERACTIVE; 1345 21926 break; 1346 21927 case ProcessList.SCHED_GROUP_TOP_APP: 1347 21928 case ProcessList.SCHED_GROUP_TOP_APP_BOUND: 1348 21929 processGroup = THREAD_GROUP_TOP_APP; 1349 21930 break; 1350 21931 default: 1351 21932 processGroup = THREAD_GROUP_DEFAULT; 1352 21933 break; 1353 21934 } 1354 21935 long oldId = Binder.clearCallingIdentity(); 1355 21936 try { 1356 21937 setProcessGroup(app.pid, processGroup); 1357 21938 if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) { 1358 21939 // do nothing if we already switched to RT 1359 21940 if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) { 1360 21941 mVrController.onTopProcChangedLocked(app); 1361 21942 if (mUseFifoUiScheduling) { 1362 21943 // Switch UI pipeline for app to SCHED_FIFO 1363 21944 app.savedPriority = Process.getThreadPriority(app.pid); 1364 21945 scheduleAsFifoPriority(app.pid, /* suppressLogs */true); 1365 21946 if (app.renderThreadTid != 0) { 1366 21947 scheduleAsFifoPriority(app.renderThreadTid, 1367 21948 /* suppressLogs */true); 1368 21949 if (DEBUG_OOM_ADJ) { 1369 21950 Slog.d("UI_FIFO", "Set RenderThread (TID " + 1370 21951 app.renderThreadTid + ") to FIFO"); 1371 21952 } 1372 21953 } else { 1373 21954 if (DEBUG_OOM_ADJ) { 1374 21955 Slog.d("UI_FIFO", "Not setting RenderThread TID"); 1375 21956 } 1376 21957 } 1377 21958 } else { 1378 21959 // Boost priority for top app UI and render threads 1379 21960 setThreadPriority(app.pid, TOP_APP_PRIORITY_BOOST); 1380 21961 if (app.renderThreadTid != 0) { 1381 21962 try { 1382 21963 setThreadPriority(app.renderThreadTid, 1383 21964 TOP_APP_PRIORITY_BOOST); 1384 21965 } catch (IllegalArgumentException e) { 1385 21966 // thread died, ignore 1386 21967 } 1387 21968 } 1388 21969 } 1389 21970 } 1390 21971 } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP && 1391 21972 app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) { 1392 21973 mVrController.onTopProcChangedLocked(app); 1393 21974 if (mUseFifoUiScheduling) { 1394 21975 // Reset UI pipeline to SCHED_OTHER 1395 21976 setThreadScheduler(app.pid, SCHED_OTHER, 0); 1396 21977 setThreadPriority(app.pid, app.savedPriority); 1397 21978 if (app.renderThreadTid != 0) { 1398 21979 setThreadScheduler(app.renderThreadTid, 1399 21980 SCHED_OTHER, 0); 1400 21981 setThreadPriority(app.renderThreadTid, -4); 1401 21982 } 1402 21983 } else { 1403 21984 // Reset priority for top app UI and render threads 1404 21985 setThreadPriority(app.pid, 0); 1405 21986 if (app.renderThreadTid != 0) { 1406 21987 setThreadPriority(app.renderThreadTid, 0); 1407 21988 } 1408 21989 } 1409 21990 } 1410 21991 } catch (Exception e) { 1411 21992 if (false) { 1412 21993 Slog.w(TAG, "Failed setting process group of " + app.pid 1413 21994 + " to " + app.curSchedGroup); 1414 21995 Slog.w(TAG, "at location", e); 1415 21996 } 1416 21997 } finally { 1417 21998 Binder.restoreCallingIdentity(oldId); 1418 21999 } 1419 22000 } 1420 22001 } 1421 22002 if (app.repForegroundActivities != app.foregroundActivities) { 1422 22003 app.repForegroundActivities = app.foregroundActivities; 1423 22004 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 1424 22005 } 1425 22006 if (app.repProcState != app.curProcState) { 1426 22007 app.repProcState = app.curProcState; 1427 22008 if (app.thread != null) { 1428 22009 try { 1429 22010 if (false) { 1430 22011 //RuntimeException h = new RuntimeException("here"); 1431 22012 Slog.i(TAG, "Sending new process state " + app.repProcState 1432 22013 + " to " + app /*, h*/); 1433 22014 } 1434 22015 app.thread.setProcessState(app.repProcState); 1435 22016 } catch (RemoteException e) { 1436 22017 } 1437 22018 } 1438 22019 } 1439 22020 if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT 1440 22021 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) { 1441 22022 if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) { 1442 22023 // Experimental code to more aggressively collect pss while 1443 22024 // running test... the problem is that this tends to collect 1444 22025 // the data right when a process is transitioning between process 1445 22026 // states, which well tend to give noisy data. 1446 22027 long start = SystemClock.uptimeMillis(); 1447 22028 long pss = Debug.getPss(app.pid, mTmpLong, null); 1448 22029 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now); 1449 22030 mPendingPssProcesses.remove(app); 1450 22031 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState 1451 22032 + " to " + app.curProcState + ": " 1452 22033 + (SystemClock.uptimeMillis()-start) + "ms"); 1453 22034 } 1454 22035 app.lastStateTime = now; 1455 22036 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 1456 22037 mTestPssMode, isSleepingLocked(), now); 1457 22038 if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from " 1458 22039 + ProcessList.makeProcStateString(app.setProcState) + " to " 1459 22040 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 1460 22041 + (app.nextPssTime-now) + ": " + app); 1461 22042 } else { 1462 22043 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 1463 22044 && now > (app.lastStateTime+ProcessList.minTimeFromStateChange( 1464 22045 mTestPssMode)))) { 1465 22046 requestPssLocked(app, app.setProcState); 1466 22047 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 1467 22048 mTestPssMode, isSleepingLocked(), now); 1468 22049 } else if (false && DEBUG_PSS) Slog.d(TAG_PSS, 1469 22050 "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 1470 22051 } 1471 22052 if (app.setProcState != app.curProcState) { 1472 22053 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ, 1473 22054 "Proc state change of " + app.processName 1474 22055 + " to " + app.curProcState); 1475 22056 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 1476 22057 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 1477 22058 if (setImportant && !curImportant) { 1478 22059 // This app is no longer something we consider important enough to allow to 1479 22060 // use arbitrary amounts of battery power. Note 1480 22061 // its current wake lock time to later know to kill it if 1481 22062 // it is not behaving well. 1482 22063 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 1483 22064 synchronized (stats) { 1484 22065 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 1485 22066 app.pid, nowElapsed); 1486 22067 } 1487 22068 app.lastCpuTime = app.curCpuTime; 1488 22069 1489 22070 } 1490 22071 // Inform UsageStats of important process state change 1491 22072 // Must be called before updating setProcState 1492 22073 maybeUpdateUsageStatsLocked(app, nowElapsed); 1493 22074 1494 22075 app.setProcState = app.curProcState; 1495 22076 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 1496 22077 app.notCachedSinceIdle = false; 1497 22078 } 1498 22079 if (!doingAll) { 1499 22080 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 1500 22081 } else { 1501 22082 app.procStateChanged = true; 1502 22083 } 1503 22084 } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime) 1504 22085 > mConstants.USAGE_STATS_INTERACTION_INTERVAL) { 1505 22086 // For apps that sit around for a long time in the interactive state, we need 1506 22087 // to report this at least once a day so they don't go idle. 1507 22088 maybeUpdateUsageStatsLocked(app, nowElapsed); 1508 22089 } 1509 22090 1510 22091 if (changes != 0) { 1511 22092 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS, 1512 22093 "Changes in " + app + ": " + changes); 1513 22094 int i = mPendingProcessChanges.size()-1; 1514 22095 ProcessChangeItem item = null; 1515 22096 while (i >= 0) { 1516 22097 item = mPendingProcessChanges.get(i); 1517 22098 if (item.pid == app.pid) { 1518 22099 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS, 1519 22100 "Re-using existing item: " + item); 1520 22101 break; 1521 22102 } 1522 22103 i--; 1523 22104 } 1524 22105 if (i < 0) { 1525 22106 // No existing item in pending changes; need a new one. 1526 22107 final int NA = mAvailProcessChanges.size(); 1527 22108 if (NA > 0) { 1528 22109 item = mAvailProcessChanges.remove(NA-1); 1529 22110 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS, 1530 22111 "Retrieving available item: " + item); 1531 22112 } else { 1532 22113 item = new ProcessChangeItem(); 1533 22114 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS, 1534 22115 "Allocating new item: " + item); 1535 22116 } 1536 22117 item.changes = 0; 1537 22118 item.pid = app.pid; 1538 22119 item.uid = app.info.uid; 1539 22120 if (mPendingProcessChanges.size() == 0) { 1540 22121 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS, 1541 22122 "*** Enqueueing dispatch processes changed!"); 1542 22123 mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget(); 1543 22124 } 1544 22125 mPendingProcessChanges.add(item); 1545 22126 } 1546 22127 item.changes |= changes; 1547 22128 item.foregroundActivities = app.repForegroundActivities; 1548 22129 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS, 1549 22130 "Item " + Integer.toHexString(System.identityHashCode(item)) 1550 22131 + " " + app.toShortString() + ": changes=" + item.changes 1551 22132 + " foreground=" + item.foregroundActivities 1552 22133 + " type=" + app.adjType + " source=" + app.adjSource 1553 22134 + " target=" + app.adjTarget); 1554 22135 } 1555 22136 1556 22137 return success; 1557 22138 } 1558 22139 1559 22140 private boolean isEphemeralLocked(int uid) { 1560 22141 String packages[] = mContext.getPackageManager().getPackagesForUid(uid); 1561 22142 if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid 1562 22143 return false; 1563 22144 } 1564 22145 return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid), 1565 22146 packages[0]); 1566 22147 } 1567 22148 1568 22149 @VisibleForTesting 1569 22150 final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) { 1570 22151 final UidRecord.ChangeItem pendingChange; 1571 22152 if (uidRec == null || uidRec.pendingChange == null) { 1572 22153 if (mPendingUidChanges.size() == 0) { 1573 22154 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, 1574 22155 "*** Enqueueing dispatch uid changed!"); 1575 22156 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget(); 1576 22157 } 1577 22158 final int NA = mAvailUidChanges.size(); 1578 22159 if (NA > 0) { 1579 22160 pendingChange = mAvailUidChanges.remove(NA-1); 1580 22161 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, 1581 22162 "Retrieving available item: " + pendingChange); 1582 22163 } else { 1583 22164 pendingChange = new UidRecord.ChangeItem(); 1584 22165 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, 1585 22166 "Allocating new item: " + pendingChange); 1586 22167 } 1587 22168 if (uidRec != null) { 1588 22169 uidRec.pendingChange = pendingChange; 1589 22170 if (change == UidRecord.CHANGE_GONE && !uidRec.idle) { 1590 22171 // If this uid is going away, and we haven't yet reported it is gone, 1591 22172 // then do so now. 1592 22173 change = UidRecord.CHANGE_GONE_IDLE; 1593 22174 } 1594 22175 } else if (uid < 0) { 1595 22176 throw new IllegalArgumentException("No UidRecord or uid"); 1596 22177 } 1597 22178 pendingChange.uidRecord = uidRec; 1598 22179 pendingChange.uid = uidRec != null ? uidRec.uid : uid; 1599 22180 mPendingUidChanges.add(pendingChange); 1600 22181 } else { 1601 22182 pendingChange = uidRec.pendingChange; 1602 22183 if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) { 1603 22184 change = UidRecord.CHANGE_GONE_IDLE; 1604 22185 } 1605 22186 } 1606 22187 pendingChange.change = change; 1607 22188 pendingChange.processState = uidRec != null 1608 22189 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT; 1609 22190 pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid); 1610 22191 pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0; 1611 22192 if (uidRec != null) { 1612 22193 uidRec.updateLastDispatchedProcStateSeq(change); 1613 22194 } 1614 22195 1615 22196 // Directly update the power manager, since we sit on top of it and it is critical 1616 22197 // it be kept in sync (so wake locks will be held as soon as appropriate). 1617 22198 if (mLocalPowerManager != null) { 1618 22199 switch (change) { 1619 22200 case UidRecord.CHANGE_GONE: 1620 22201 case UidRecord.CHANGE_GONE_IDLE: 1621 22202 mLocalPowerManager.uidGone(pendingChange.uid); 1622 22203 break; 1623 22204 case UidRecord.CHANGE_IDLE: 1624 22205 mLocalPowerManager.uidIdle(pendingChange.uid); 1625 22206 break; 1626 22207 case UidRecord.CHANGE_ACTIVE: 1627 22208 mLocalPowerManager.uidActive(pendingChange.uid); 1628 22209 break; 1629 22210 default: 1630 22211 mLocalPowerManager.updateUidProcState(pendingChange.uid, 1631 22212 pendingChange.processState); 1632 22213 break; 1633 22214 } 1634 22215 } 1635 22216 } 1636 22217 1637 22218 private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName, 1638 22219 String authority) { 1639 22220 if (app == null) return; 1640 22221 if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 1641 22222 UserState userState = mUserController.getStartedUserStateLocked(app.userId); 1642 22223 if (userState == null) return; 1643 22224 final long now = SystemClock.elapsedRealtime(); 1644 22225 Long lastReported = userState.mProviderLastReportedFg.get(authority); 1645 22226 if (lastReported == null || lastReported < now - 60 * 1000L) { 1646 22227 if (mSystemReady) { 1647 22228 // Cannot touch the user stats if not system ready 1648 22229 mUsageStatsService.reportContentProviderUsage( 1649 22230 authority, providerPkgName, app.userId); 1650 22231 } 1651 22232 userState.mProviderLastReportedFg.put(authority, now); 1652 22233 } 1653 22234 } 1654 22235 } 1655 22236 1656 22237 private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) { 1657 22238 if (DEBUG_USAGE_STATS) { 1658 22239 Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList()) 1659 22240 + "] state changes: old = " + app.setProcState + ", new = " 1660 22241 + app.curProcState); 1661 22242 } 1662 22243 if (mUsageStatsService == null) { 1663 22244 return; 1664 22245 } 1665 22246 boolean isInteraction; 1666 22247 // To avoid some abuse patterns, we are going to be careful about what we consider 1667 22248 // to be an app interaction. Being the top activity doesn't count while the display 1668 22249 // is sleeping, nor do short foreground services. 1669 22250 if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) { 1670 22251 isInteraction = true; 1671 22252 app.fgInteractionTime = 0; 1672 22253 } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) { 1673 22254 if (app.fgInteractionTime == 0) { 1674 22255 app.fgInteractionTime = nowElapsed; 1675 22256 isInteraction = false; 1676 22257 } else { 1677 22258 isInteraction = nowElapsed > app.fgInteractionTime 1678 22259 + mConstants.SERVICE_USAGE_INTERACTION_TIME; 1679 22260 } 1680 22261 } else { 1681 22262 isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 1682 22263 app.fgInteractionTime = 0; 1683 22264 } 1684 22265 if (isInteraction && (!app.reportedInteraction || (nowElapsed-app.interactionEventTime) 1685 22266 > mConstants.USAGE_STATS_INTERACTION_INTERVAL)) { 1686 22267 app.interactionEventTime = nowElapsed; 1687 22268 String[] packages = app.getPackageList(); 1688 22269 if (packages != null) { 1689 22270 for (int i = 0; i < packages.length; i++) { 1690 22271 mUsageStatsService.reportEvent(packages[i], app.userId, 1691 22272 UsageEvents.Event.SYSTEM_INTERACTION); 1692 22273 } 1693 22274 } 1694 22275 } 1695 22276 app.reportedInteraction = isInteraction; 1696 22277 if (!isInteraction) { 1697 22278 app.interactionEventTime = 0; 1698 22279 } 1699 22280 } 1700 22281 1701 22282 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 1702 22283 if (proc.thread != null) { 1703 22284 if (proc.baseProcessTracker != null) { 1704 22285 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 1705 22286 } 1706 22287 } 1707 22288 } 1708 22289 1709 22290 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 1710 22291 ProcessRecord TOP_APP, boolean doingAll, long now) { 1711 22292 if (app.thread == null) { 1712 22293 return false; 1713 22294 } 1714 22295 1715 22296 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 1716 22297 1717 22298 return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime()); 1718 22299 } 1719 22300 1720 22301 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 1721 22302 boolean oomAdj) { 1722 22303 if (isForeground != proc.foregroundServices) { 1723 22304 proc.foregroundServices = isForeground; 1724 22305 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 1725 22306 proc.info.uid); 1726 22307 if (isForeground) { 1727 22308 if (curProcs == null) { 1728 22309 curProcs = new ArrayList<ProcessRecord>(); 1729 22310 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 1730 22311 } 1731 22312 if (!curProcs.contains(proc)) { 1732 22313 curProcs.add(proc); 1733 22314 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 1734 22315 proc.info.packageName, proc.info.uid); 1735 22316 } 1736 22317 } else { 1737 22318 if (curProcs != null) { 1738 22319 if (curProcs.remove(proc)) { 1739 22320 mBatteryStatsService.noteEvent( 1740 22321 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 1741 22322 proc.info.packageName, proc.info.uid); 1742 22323 if (curProcs.size() <= 0) { 1743 22324 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 1744 22325 } 1745 22326 } 1746 22327 } 1747 22328 } 1748 22329 if (oomAdj) { 1749 22330 updateOomAdjLocked(); 1750 22331 } 1751 22332 } 1752 22333 } 1753 22334 1754 22335 private final ActivityRecord resumedAppLocked() { 1755 22336 ActivityRecord act = mStackSupervisor.getResumedActivityLocked(); 1756 22337 String pkg; 1757 22338 int uid; 1758 22339 if (act != null) { 1759 22340 pkg = act.packageName; 1760 22341 uid = act.info.applicationInfo.uid; 1761 22342 } else { 1762 22343 pkg = null; 1763 22344 uid = -1; 1764 22345 } 1765 22346 // Has the UID or resumed package name changed? 1766 22347 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 1767 22348 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 1768 22349 if (mCurResumedPackage != null) { 1769 22350 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 1770 22351 mCurResumedPackage, mCurResumedUid); 1771 22352 } 1772 22353 mCurResumedPackage = pkg; 1773 22354 mCurResumedUid = uid; 1774 22355 if (mCurResumedPackage != null) { 1775 22356 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 1776 22357 mCurResumedPackage, mCurResumedUid); 1777 22358 } 1778 22359 } 1779 22360 return act; 1780 22361 } 1781 22362 1782 22363 /** 1783 22364 * Update OomAdj for a specific process. 1784 22365 * @param app The process to update 1785 22366 * @param oomAdjAll If it's ok to call updateOomAdjLocked() for all running apps 1786 22367 * if necessary, or skip. 1787 22368 * @return whether updateOomAdjLocked(app) was successful. 1788 22369 */ 1789 22370 final boolean updateOomAdjLocked(ProcessRecord app, boolean oomAdjAll) { 1790 22371 final ActivityRecord TOP_ACT = resumedAppLocked(); 1791 22372 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 1792 22373 final boolean wasCached = app.cached; 1793 22374 1794 22375 mAdjSeq++; 1795 22376 1796 22377 // This is the desired cached adjusment we want to tell it to use. 1797 22378 // If our app is currently cached, we know it, and that is it. Otherwise, 1798 22379 // we don't know it yet, and it needs to now be cached we will then 1799 22380 // need to do a complete oom adj. 1800 22381 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 1801 22382 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 1802 22383 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 1803 22384 SystemClock.uptimeMillis()); 1804 22385 if (oomAdjAll 1805 22386 && (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ)) { 1806 22387 // Changed to/from cached state, so apps after it in the LRU 1807 22388 // list may also be changed. 1808 22389 updateOomAdjLocked(); 1809 22390 } 1810 22391 return success; 1811 22392 } 1812 22393 1813 22394 final void updateOomAdjLocked() { 1814 22395 final ActivityRecord TOP_ACT = resumedAppLocked(); 1815 22396 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 1816 22397 final long now = SystemClock.uptimeMillis(); 1817 22398 final long nowElapsed = SystemClock.elapsedRealtime(); 1818 22399 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 1819 22400 final int N = mLruProcesses.size(); 1820 22401 1821 22402 if (false) { 1822 22403 RuntimeException e = new RuntimeException(); 1823 22404 e.fillInStackTrace(); 1824 22405 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 1825 22406 } 1826 22407 1827 22408 // Reset state in all uid records. 1828 22409 for (int i=mActiveUids.size()-1; i>=0; i--) { 1829 22410 final UidRecord uidRec = mActiveUids.valueAt(i); 1830 22411 if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, 1831 22412 "Starting update of " + uidRec); 1832 22413 uidRec.reset(); 1833 22414 } 1834 22415 1835 22416 mStackSupervisor.rankTaskLayersIfNeeded(); 1836 22417 1837 22418 mAdjSeq++; 1838 22419 mNewNumServiceProcs = 0; 1839 22420 mNewNumAServiceProcs = 0; 1840 22421 1841 22422 final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES; 1842 22423 final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit; 1843 22424 1844 22425 // Let's determine how many processes we have running vs. 1845 22426 // how many slots we have for background processes; we may want 1846 22427 // to put multiple processes in a slot of there are enough of 1847 22428 // them. 1848 22429 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 1849 22430 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 1850 22431 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 1851 22432 if (numEmptyProcs > cachedProcessLimit) { 1852 22433 // If there are more empty processes than our limit on cached 1853 22434 // processes, then use the cached process limit for the factor. 1854 22435 // This ensures that the really old empty processes get pushed 1855 22436 // down to the bottom, so if we are running low on memory we will 1856 22437 // have a better chance at keeping around more cached processes 1857 22438 // instead of a gazillion empty processes. 1858 22439 numEmptyProcs = cachedProcessLimit; 1859 22440 } 1860 22441 int emptyFactor = numEmptyProcs/numSlots; 1861 22442 if (emptyFactor < 1) emptyFactor = 1; 1862 22443 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 1863 22444 if (cachedFactor < 1) cachedFactor = 1; 1864 22445 int stepCached = 0; 1865 22446 int stepEmpty = 0; 1866 22447 int numCached = 0; 1867 22448 int numEmpty = 0; 1868 22449 int numTrimming = 0; 1869 22450 1870 22451 mNumNonCachedProcs = 0; 1871 22452 mNumCachedHiddenProcs = 0; 1872 22453 1873 22454 // First update the OOM adjustment for each of the 1874 22455 // application processes based on their current state. 1875 22456 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 1876 22457 int nextCachedAdj = curCachedAdj+1; 1877 22458 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 1878 22459 int nextEmptyAdj = curEmptyAdj+2; 1879 22460 for (int i=N-1; i>=0; i--) { 1880 22461 ProcessRecord app = mLruProcesses.get(i); 1881 22462 if (!app.killedByAm && app.thread != null) { 1882 22463 app.procStateChanged = false; 1883 22464 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 1884 22465 1885 22466 // If we haven't yet assigned the final cached adj 1886 22467 // to the process, do that now. 1887 22468 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 1888 22469 switch (app.curProcState) { 1889 22470 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 1890 22471 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 1891 22472 // This process is a cached process holding activities... 1892 22473 // assign it the next cached value for that type, and then 1893 22474 // step that cached level. 1894 22475 app.curRawAdj = curCachedAdj; 1895 22476 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 1896 22477 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i 1897 22478 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 1898 22479 + ")"); 1899 22480 if (curCachedAdj != nextCachedAdj) { 1900 22481 stepCached++; 1901 22482 if (stepCached >= cachedFactor) { 1902 22483 stepCached = 0; 1903 22484 curCachedAdj = nextCachedAdj; 1904 22485 nextCachedAdj += 2; 1905 22486 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 1906 22487 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 1907 22488 } 1908 22489 } 1909 22490 } 1910 22491 break; 1911 22492 default: 1912 22493 // For everything else, assign next empty cached process 1913 22494 // level and bump that up. Note that this means that 1914 22495 // long-running services that have dropped down to the 1915 22496 // cached level will be treated as empty (since their process 1916 22497 // state is still as a service), which is what we want. 1917 22498 app.curRawAdj = curEmptyAdj; 1918 22499 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 1919 22500 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i 1920 22501 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 1921 22502 + ")"); 1922 22503 if (curEmptyAdj != nextEmptyAdj) { 1923 22504 stepEmpty++; 1924 22505 if (stepEmpty >= emptyFactor) { 1925 22506 stepEmpty = 0; 1926 22507 curEmptyAdj = nextEmptyAdj; 1927 22508 nextEmptyAdj += 2; 1928 22509 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 1929 22510 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 1930 22511 } 1931 22512 } 1932 22513 } 1933 22514 break; 1934 22515 } 1935 22516 } 1936 22517 1937 22518 applyOomAdjLocked(app, true, now, nowElapsed); 1938 22519 1939 22520 // Count the number of process types. 1940 22521 switch (app.curProcState) { 1941 22522 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 1942 22523 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 1943 22524 mNumCachedHiddenProcs++; 1944 22525 numCached++; 1945 22526 if (numCached > cachedProcessLimit) { 1946 22527 app.kill("cached #" + numCached, true); 1947 22528 } 1948 22529 break; 1949 22530 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 1950 22531 if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES 1951 22532 && app.lastActivityTime < oldTime) { 1952 22533 app.kill("empty for " 1953 22534 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 1954 22535 / 1000) + "s", true); 1955 22536 } else { 1956 22537 numEmpty++; 1957 22538 if (numEmpty > emptyProcessLimit) { 1958 22539 app.kill("empty #" + numEmpty, true); 1959 22540 } 1960 22541 } 1961 22542 break; 1962 22543 default: 1963 22544 mNumNonCachedProcs++; 1964 22545 break; 1965 22546 } 1966 22547 1967 22548 if (app.isolated && app.services.size() <= 0) { 1968 22549 // If this is an isolated process, and there are no 1969 22550 // services running in it, then the process is no longer 1970 22551 // needed. We agressively kill these because we can by 1971 22552 // definition not re-use the same process again, and it is 1972 22553 // good to avoid having whatever code was running in them 1973 22554 // left sitting around after no longer needed. 1974 22555 app.kill("isolated not needed", true); 1975 22556 } else { 1976 22557 // Keeping this process, update its uid. 1977 22558 final UidRecord uidRec = app.uidRecord; 1978 22559 if (uidRec != null) { 1979 22560 uidRec.ephemeral = app.info.isInstantApp(); 1980 22561 if (uidRec.curProcState > app.curProcState) { 1981 22562 uidRec.curProcState = app.curProcState; 1982 22563 } 1983 22564 if (app.foregroundServices) { 1984 22565 uidRec.foregroundServices = true; 1985 22566 } 1986 22567 } 1987 22568 } 1988 22569 1989 22570 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 1990 22571 && !app.killedByAm) { 1991 22572 numTrimming++; 1992 22573 } 1993 22574 } 1994 22575 } 1995 22576 1996 22577 incrementProcStateSeqAndNotifyAppsLocked(); 1997 22578 1998 22579 mNumServiceProcs = mNewNumServiceProcs; 1999 22580 2000 22581 // Now determine the memory trimming level of background processes. 2001 22582 // Unfortunately we need to start at the back of the list to do this 2002 22583 // properly. We only do this if the number of background apps we 2003 22584 // are managing to keep around is less than half the maximum we desire; 2004 22585 // if we are keeping a good number around, we'll let them use whatever 2005 22586 // memory they want. 2006 22587 final int numCachedAndEmpty = numCached + numEmpty; 2007 22588 int memFactor; 2008 22589 if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES 2009 22590 && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) { 2010 22591 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 2011 22592 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 2012 22593 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 2013 22594 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 2014 22595 } else { 2015 22596 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 2016 22597 } 2017 22598 } else { 2018 22599 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 2019 22600 } 2020 22601 // We always allow the memory level to go up (better). We only allow it to go 2021 22602 // down if we are in a state where that is allowed, *and* the total number of processes 2022 22603 // has gone down since last time. 2023 22604 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor 2024 22605 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel 2025 22606 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses); 2026 22607 if (memFactor > mLastMemoryLevel) { 2027 22608 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 2028 22609 memFactor = mLastMemoryLevel; 2029 22610 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!"); 2030 22611 } 2031 22612 } 2032 22613 if (memFactor != mLastMemoryLevel) { 2033 22614 EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel); 2034 22615 } 2035 22616 mLastMemoryLevel = memFactor; 2036 22617 mLastNumProcesses = mLruProcesses.size(); 2037 22618 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now); 2038 22619 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 2039 22620 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 2040 22621 if (mLowRamStartTime == 0) { 2041 22622 mLowRamStartTime = now; 2042 22623 } 2043 22624 int step = 0; 2044 22625 int fgTrimLevel; 2045 22626 switch (memFactor) { 2046 22627 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 2047 22628 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 2048 22629 break; 2049 22630 case ProcessStats.ADJ_MEM_FACTOR_LOW: 2050 22631 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 2051 22632 break; 2052 22633 default: 2053 22634 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 2054 22635 break; 2055 22636 } 2056 22637 int factor = numTrimming/3; 2057 22638 int minFactor = 2; 2058 22639 if (mHomeProcess != null) minFactor++; 2059 22640 if (mPreviousProcess != null) minFactor++; 2060 22641 if (factor < minFactor) factor = minFactor; 2061 22642 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 2062 22643 for (int i=N-1; i>=0; i--) { 2063 22644 ProcessRecord app = mLruProcesses.get(i); 2064 22645 if (allChanged || app.procStateChanged) { 2065 22646 setProcessTrackerStateLocked(app, trackerMemFactor, now); 2066 22647 app.procStateChanged = false; 2067 22648 } 2068 22649 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 2069 22650 && !app.killedByAm) { 2070 22651 if (app.trimMemoryLevel < curLevel && app.thread != null) { 2071 22652 try { 2072 22653 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ, 2073 22654 "Trimming memory of " + app.processName + " to " + curLevel); 2074 22655 app.thread.scheduleTrimMemory(curLevel); 2075 22656 } catch (RemoteException e) { 2076 22657 } 2077 22658 if (false) { 2078 22659 // For now we won't do this; our memory trimming seems 2079 22660 // to be good enough at this point that destroying 2080 22661 // activities causes more harm than good. 2081 22662 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 2082 22663 && app != mHomeProcess && app != mPreviousProcess) { 2083 22664 // Need to do this on its own message because the stack may not 2084 22665 // be in a consistent state at this point. 2085 22666 // For these apps we will also finish their activities 2086 22667 // to help them free memory. 2087 22668 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 2088 22669 } 2089 22670 } 2090 22671 } 2091 22672 app.trimMemoryLevel = curLevel; 2092 22673 step++; 2093 22674 if (step >= factor) { 2094 22675 step = 0; 2095 22676 switch (curLevel) { 2096 22677 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 2097 22678 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 2098 22679 break; 2099 22680 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 2100 22681 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 2101 22682 break; 2102 22683 } 2103 22684 } 2104 22685 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 2105 22686 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 2106 22687 && app.thread != null) { 2107 22688 try { 2108 22689 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ, 2109 22690 "Trimming memory of heavy-weight " + app.processName 2110 22691 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 2111 22692 app.thread.scheduleTrimMemory( 2112 22693 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 2113 22694 } catch (RemoteException e) { 2114 22695 } 2115 22696 } 2116 22697 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 2117 22698 } else { 2118 22699 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 2119 22700 || app.systemNoUi) && app.pendingUiClean) { 2120 22701 // If this application is now in the background and it 2121 22702 // had done UI, then give it the special trim level to 2122 22703 // have it free UI resources. 2123 22704 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 2124 22705 if (app.trimMemoryLevel < level && app.thread != null) { 2125 22706 try { 2126 22707 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ, 2127 22708 "Trimming memory of bg-ui " + app.processName 2128 22709 + " to " + level); 2129 22710 app.thread.scheduleTrimMemory(level); 2130 22711 } catch (RemoteException e) { 2131 22712 } 2132 22713 } 2133 22714 app.pendingUiClean = false; 2134 22715 } 2135 22716 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 2136 22717 try { 2137 22718 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ, 2138 22719 "Trimming memory of fg " + app.processName 2139 22720 + " to " + fgTrimLevel); 2140 22721 app.thread.scheduleTrimMemory(fgTrimLevel); 2141 22722 } catch (RemoteException e) { 2142 22723 } 2143 22724 } 2144 22725 app.trimMemoryLevel = fgTrimLevel; 2145 22726 } 2146 22727 } 2147 22728 } else { 2148 22729 if (mLowRamStartTime != 0) { 2149 22730 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 2150 22731 mLowRamStartTime = 0; 2151 22732 } 2152 22733 for (int i=N-1; i>=0; i--) { 2153 22734 ProcessRecord app = mLruProcesses.get(i); 2154 22735 if (allChanged || app.procStateChanged) { 2155 22736 setProcessTrackerStateLocked(app, trackerMemFactor, now); 2156 22737 app.procStateChanged = false; 2157 22738 } 2158 22739 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 2159 22740 || app.systemNoUi) && app.pendingUiClean) { 2160 22741 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 2161 22742 && app.thread != null) { 2162 22743 try { 2163 22744 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ, 2164 22745 "Trimming memory of ui hidden " + app.processName 2165 22746 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 2166 22747 app.thread.scheduleTrimMemory( 2167 22748 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 2168 22749 } catch (RemoteException e) { 2169 22750 } 2170 22751 } 2171 22752 app.pendingUiClean = false; 2172 22753 } 2173 22754 app.trimMemoryLevel = 0; 2174 22755 } 2175 22756 } 2176 22757 2177 22758 if (mAlwaysFinishActivities) { 2178 22759 // Need to do this on its own message because the stack may not 2179 22760 // be in a consistent state at this point. 2180 22761 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 2181 22762 } 2182 22763 2183 22764 if (allChanged) { 2184 22765 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 2185 22766 } 2186 22767 2187 22768 // Update from any uid changes. 2188 22769 if (mLocalPowerManager != null) { 2189 22770 mLocalPowerManager.startUidChanges(); 2190 22771 } 2191 22772 for (int i=mActiveUids.size()-1; i>=0; i--) { 2192 22773 final UidRecord uidRec = mActiveUids.valueAt(i); 2193 22774 int uidChange = UidRecord.CHANGE_PROCSTATE; 2194 22775 if (uidRec.setProcState != uidRec.curProcState 2195 22776 || uidRec.setWhitelist != uidRec.curWhitelist) { 2196 22777 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, 2197 22778 "Changes in " + uidRec + ": proc state from " + uidRec.setProcState 2198 22779 + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist 2199 22780 + " to " + uidRec.curWhitelist); 2200 22781 if (ActivityManager.isProcStateBackground(uidRec.curProcState) 2201 22782 && !uidRec.curWhitelist) { 2202 22783 // UID is now in the background (and not on the temp whitelist). Was it 2203 22784 // previously in the foreground (or on the temp whitelist)? 2204 22785 if (!ActivityManager.isProcStateBackground(uidRec.setProcState) 2205 22786 || uidRec.setWhitelist) { 2206 22787 uidRec.lastBackgroundTime = nowElapsed; 2207 22788 if (!mHandler.hasMessages(IDLE_UIDS_MSG)) { 2208 22789 // Note: the background settle time is in elapsed realtime, while 2209 22790 // the handler time base is uptime. All this means is that we may 2210 22791 // stop background uids later than we had intended, but that only 2211 22792 // happens because the device was sleeping so we are okay anyway. 2212 22793 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, 2213 22794 mConstants.BACKGROUND_SETTLE_TIME); 2214 22795 } 2215 22796 } 2216 22797 } else { 2217 22798 if (uidRec.idle) { 2218 22799 uidChange = UidRecord.CHANGE_ACTIVE; 2219 22800 EventLogTags.writeAmUidActive(uidRec.uid); 2220 22801 uidRec.idle = false; 2221 22802 } 2222 22803 uidRec.lastBackgroundTime = 0; 2223 22804 } 2224 22805 uidRec.setProcState = uidRec.curProcState; 2225 22806 uidRec.setWhitelist = uidRec.curWhitelist; 2226 22807 enqueueUidChangeLocked(uidRec, -1, uidChange); 2227 22808 noteUidProcessState(uidRec.uid, uidRec.curProcState); 2228 22809 if (uidRec.foregroundServices) { 2229 22810 mServices.foregroundServiceProcStateChangedLocked(uidRec); 2230 22811 } 2231 22812 } 2232 22813 } 2233 22814 if (mLocalPowerManager != null) { 2234 22815 mLocalPowerManager.finishUidChanges(); 2235 22816 } 2236 22817 2237 22818 if (mProcessStats.shouldWriteNowLocked(now)) { 2238 22819 mHandler.post(new Runnable() { 2239 22820 @Override public void run() { 2240 22821 synchronized (ActivityManagerService.this) { 2241 22822 mProcessStats.writeStateAsyncLocked(); 2242 22823 } 2243 22824 } 2244 22825 }); 2245 22826 } 2246 22827 2247 22828 if (DEBUG_OOM_ADJ) { 2248 22829 final long duration = SystemClock.uptimeMillis() - now; 2249 22830 if (false) { 2250 22831 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms", 2251 22832 new RuntimeException("here").fillInStackTrace()); 2252 22833 } else { 2253 22834 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms"); 2254 22835 } 2255 22836 } 2256 22837 } 2257 22838 2258 22839 @Override 2259 22840 public void makePackageIdle(String packageName, int userId) { 2260 22841 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 2261 22842 != PackageManager.PERMISSION_GRANTED) { 2262 22843 String msg = "Permission Denial: makePackageIdle() from pid=" 2263 22844 + Binder.getCallingPid() 2264 22845 + ", uid=" + Binder.getCallingUid() 2265 22846 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 2266 22847 Slog.w(TAG, msg); 2267 22848 throw new SecurityException(msg); 2268 22849 } 2269 22850 final int callingPid = Binder.getCallingPid(); 2270 22851 userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(), 2271 22852 userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null); 2272 22853 long callingId = Binder.clearCallingIdentity(); 2273 22854 synchronized(this) { 2274 22855 try { 2275 22856 IPackageManager pm = AppGlobals.getPackageManager(); 2276 22857 int pkgUid = -1; 2277 22858 try { 2278 22859 pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES 2279 22860 | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM); 2280 22861 } catch (RemoteException e) { 2281 22862 } 2282 22863 if (pkgUid == -1) { 2283 22864 throw new IllegalArgumentException("Unknown package name " + packageName); 2284 22865 } 2285 22866 2286 22867 if (mLocalPowerManager != null) { 2287 22868 mLocalPowerManager.startUidChanges(); 2288 22869 } 2289 22870 final int appId = UserHandle.getAppId(pkgUid); 2290 22871 final int N = mActiveUids.size(); 2291 22872 for (int i=N-1; i>=0; i--) { 2292 22873 final UidRecord uidRec = mActiveUids.valueAt(i); 2293 22874 final long bgTime = uidRec.lastBackgroundTime; 2294 22875 if (bgTime > 0 && !uidRec.idle) { 2295 22876 if (UserHandle.getAppId(uidRec.uid) == appId) { 2296 22877 if (userId == UserHandle.USER_ALL || 2297 22878 userId == UserHandle.getUserId(uidRec.uid)) { 2298 22879 EventLogTags.writeAmUidIdle(uidRec.uid); 2299 22880 uidRec.idle = true; 2300 22881 Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid) 2301 22882 + " from package " + packageName + " user " + userId); 2302 22883 doStopUidLocked(uidRec.uid, uidRec); 2303 22884 } 2304 22885 } 2305 22886 } 2306 22887 } 2307 22888 } finally { 2308 22889 if (mLocalPowerManager != null) { 2309 22890 mLocalPowerManager.finishUidChanges(); 2310 22891 } 2311 22892 Binder.restoreCallingIdentity(callingId); 2312 22893 } 2313 22894 } 2314 22895 } 2315 22896 2316 22897 final void idleUids() { 2317 22898 synchronized (this) { 2318 22899 final int N = mActiveUids.size(); 2319 22900 if (N <= 0) { 2320 22901 return; 2321 22902 } 2322 22903 final long nowElapsed = SystemClock.elapsedRealtime(); 2323 22904 final long maxBgTime = nowElapsed - mConstants.BACKGROUND_SETTLE_TIME; 2324 22905 long nextTime = 0; 2325 22906 if (mLocalPowerManager != null) { 2326 22907 mLocalPowerManager.startUidChanges(); 2327 22908 } 2328 22909 for (int i=N-1; i>=0; i--) { 2329 22910 final UidRecord uidRec = mActiveUids.valueAt(i); 2330 22911 final long bgTime = uidRec.lastBackgroundTime; 2331 22912 if (bgTime > 0 && !uidRec.idle) { 2332 22913 if (bgTime <= maxBgTime) { 2333 22914 EventLogTags.writeAmUidIdle(uidRec.uid); 2334 22915 uidRec.idle = true; 2335 22916 doStopUidLocked(uidRec.uid, uidRec); 2336 22917 } else { 2337 22918 if (nextTime == 0 || nextTime > bgTime) { 2338 22919 nextTime = bgTime; 2339 22920 } 2340 22921 } 2341 22922 } 2342 22923 } 2343 22924 if (mLocalPowerManager != null) { 2344 22925 mLocalPowerManager.finishUidChanges(); 2345 22926 } 2346 22927 if (nextTime > 0) { 2347 22928 mHandler.removeMessages(IDLE_UIDS_MSG); 2348 22929 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, 2349 22930 nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed); 2350 22931 } 2351 22932 } 2352 22933 } 2353 22934 2354 22935 /** 2355 22936 * Checks if any uid is coming from background to foreground or vice versa and if so, increments 2356 22937 * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter 2357 22938 * {@link #mProcStateSeqCounter} and notifies the app if it needs to block. 2358 22939 */ 2359 22940 @VisibleForTesting 2360 22941 @GuardedBy("this") 2361 22942 void incrementProcStateSeqAndNotifyAppsLocked() { 2362 22943 if (mWaitForNetworkTimeoutMs <= 0) { 2363 22944 return; 2364 22945 } 2365 22946 // Used for identifying which uids need to block for network. 2366 22947 ArrayList<Integer> blockingUids = null; 2367 22948 for (int i = mActiveUids.size() - 1; i >= 0; --i) { 2368 22949 final UidRecord uidRec = mActiveUids.valueAt(i); 2369 22950 // If the network is not restricted for uid, then nothing to do here. 2370 22951 if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) { 2371 22952 continue; 2372 22953 } 2373 22954 if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) { 2374 22955 continue; 2375 22956 } 2376 22957 // If process state is not changed, then there's nothing to do. 2377 22958 if (uidRec.setProcState == uidRec.curProcState) { 2378 22959 continue; 2379 22960 } 2380 22961 final int blockState = getBlockStateForUid(uidRec); 2381 22962 // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as 2382 22963 // there's nothing the app needs to do in this scenario. 2383 22964 if (blockState == NETWORK_STATE_NO_CHANGE) { 2384 22965 continue; 2385 22966 } 2386 22967 synchronized (uidRec.networkStateLock) { 2387 22968 uidRec.curProcStateSeq = ++mProcStateSeqCounter; 2388 22969 if (blockState == NETWORK_STATE_BLOCK) { 2389 22970 if (blockingUids == null) { 2390 22971 blockingUids = new ArrayList<>(); 2391 22972 } 2392 22973 blockingUids.add(uidRec.uid); 2393 22974 } else { 2394 22975 if (DEBUG_NETWORK) { 2395 22976 Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking" 2396 22977 + " threads for uid: " + uidRec); 2397 22978 } 2398 22979 if (uidRec.waitingForNetwork) { 2399 22980 uidRec.networkStateLock.notifyAll(); 2400 22981 } 2401 22982 } 2402 22983 } 2403 22984 } 2404 22985 2405 22986 // There are no uids that need to block, so nothing more to do. 2406 22987 if (blockingUids == null) { 2407 22988 return; 2408 22989 } 2409 22990 2410 22991 for (int i = mLruProcesses.size() - 1; i >= 0; --i) { 2411 22992 final ProcessRecord app = mLruProcesses.get(i); 2412 22993 if (!blockingUids.contains(app.uid)) { 2413 22994 continue; 2414 22995 } 2415 22996 if (!app.killedByAm && app.thread != null) { 2416 22997 final UidRecord uidRec = mActiveUids.get(app.uid); 2417 22998 try { 2418 22999 if (DEBUG_NETWORK) { 2419 23000 Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: " 2420 23001 + uidRec); 2421 23002 } 2422 23003 app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq); 2423 23004 } catch (RemoteException ignored) { 2424 23005 } 2425 23006 } 2426 23007 } 2427 23008 } 2428 23009 2429 23010 /** 2430 23011 * Checks if the uid is coming from background to foreground or vice versa and returns 2431 23012 * appropriate block state based on this. 2432 23013 * 2433 23014 * @return blockState based on whether the uid is coming from background to foreground or 2434 23015 * vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or 2435 23016 * {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise 2436 23017 * {@link #NETWORK_STATE_NO_CHANGE}. 2437 23018 */ 2438 23019 @VisibleForTesting 2439 23020 int getBlockStateForUid(UidRecord uidRec) { 2440 23021 // Denotes whether uid's process state is currently allowed network access. 2441 23022 final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState) 2442 23023 || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState); 2443 23024 // Denotes whether uid's process state was previously allowed network access. 2444 23025 final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState) 2445 23026 || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState); 2446 23027 2447 23028 // When the uid is coming to foreground, AMS should inform the app thread that it should 2448 23029 // block for the network rules to get updated before launching an activity. 2449 23030 if (!wasAllowed && isAllowed) { 2450 23031 return NETWORK_STATE_BLOCK; 2451 23032 } 2452 23033 // When the uid is going to background, AMS should inform the app thread that if an 2453 23034 // activity launch is blocked for the network rules to get updated, it should be unblocked. 2454 23035 if (wasAllowed && !isAllowed) { 2455 23036 return NETWORK_STATE_UNBLOCK; 2456 23037 } 2457 23038 return NETWORK_STATE_NO_CHANGE; 2458 23039 } 2459 23040 2460 23041 final void runInBackgroundDisabled(int uid) { 2461 23042 synchronized (this) { 2462 23043 UidRecord uidRec = mActiveUids.get(uid); 2463 23044 if (uidRec != null) { 2464 23045 // This uid is actually running... should it be considered background now? 2465 23046 if (uidRec.idle) { 2466 23047 doStopUidLocked(uidRec.uid, uidRec); 2467 23048 } 2468 23049 } else { 2469 23050 // This uid isn't actually running... still send a report about it being "stopped". 2470 23051 doStopUidLocked(uid, null); 2471 23052 } 2472 23053 } 2473 23054 } 2474 23055 2475 23056 final void doStopUidLocked(int uid, final UidRecord uidRec) { 2476 23057 mServices.stopInBackgroundLocked(uid); 2477 23058 enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE); 2478 23059 } 2479 23060 2480 23061 /** 2481 23062 * Whitelists {@code targetUid} to temporarily bypass Power Save mode. 2482 23063 */ 2483 23064 void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid, 2484 23065 long duration, String tag) { 2485 23066 if (DEBUG_WHITELISTS) { 2486 23067 Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", " 2487 23068 + targetUid + ", " + duration + ")"); 2488 23069 } 2489 23070 2490 23071 synchronized (mPidsSelfLocked) { 2491 23072 final ProcessRecord pr = mPidsSelfLocked.get(callerPid); 2492 23073 if (pr == null) { 2493 23074 Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid " 2494 23075 + callerPid); 2495 23076 return; 2496 23077 } 2497 23078 if (!pr.whitelistManager) { 2498 23079 if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid) 2499 23080 != PackageManager.PERMISSION_GRANTED) { 2500 23081 if (DEBUG_WHITELISTS) { 2501 23082 Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid 2502 23083 + ": pid " + callerPid + " is not allowed"); 2503 23084 } 2504 23085 return; 2505 23086 } 2506 23087 } 2507 23088 } 2508 23089 2509 23090 tempWhitelistUidLocked(targetUid, duration, tag); 2510 23091 } 2511 23092 2512 23093 /** 2513 23094 * Whitelists {@code targetUid} to temporarily bypass Power Save mode. 2514 23095 */ 2515 23096 void tempWhitelistUidLocked(int targetUid, long duration, String tag) { 2516 23097 mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag)); 2517 23098 setUidTempWhitelistStateLocked(targetUid, true); 2518 23099 mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget(); 2519 23100 } 2520 23101 2521 23102 void pushTempWhitelist() { 2522 23103 final int N; 2523 23104 final PendingTempWhitelist[] list; 2524 23105 2525 23106 // First copy out the pending changes... we need to leave them in the map for now, 2526 23107 // in case someone needs to check what is coming up while we don't have the lock held. 2527 23108 synchronized(this) { 2528 23109 N = mPendingTempWhitelist.size(); 2529 23110 list = new PendingTempWhitelist[N]; 2530 23111 for (int i = 0; i < N; i++) { 2531 23112 list[i] = mPendingTempWhitelist.valueAt(i); 2532 23113 } 2533 23114 } 2534 23115 2535 23116 // Now safely dispatch changes to device idle controller. 2536 23117 for (int i = 0; i < N; i++) { 2537 23118 PendingTempWhitelist ptw = list[i]; 2538 23119 mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid, 2539 23120 ptw.duration, true, ptw.tag); 2540 23121 } 2541 23122 2542 23123 // And now we can safely remove them from the map. 2543 23124 synchronized(this) { 2544 23125 for (int i = 0; i < N; i++) { 2545 23126 PendingTempWhitelist ptw = list[i]; 2546 23127 int index = mPendingTempWhitelist.indexOfKey(ptw.targetUid); 2547 23128 if (index >= 0 && mPendingTempWhitelist.valueAt(index) == ptw) { 2548 23129 mPendingTempWhitelist.removeAt(index); 2549 23130 } 2550 23131 } 2551 23132 } 2552 23133 } 2553 23134 2554 23135 final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) { 2555 23136 boolean changed = false; 2556 23137 for (int i=mActiveUids.size()-1; i>=0; i--) { 2557 23138 final UidRecord uidRec = mActiveUids.valueAt(i); 2558 23139 if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) { 2559 23140 uidRec.curWhitelist = onWhitelist; 2560 23141 changed = true; 2561 23142 } 2562 23143 } 2563 23144 if (changed) { 2564 23145 updateOomAdjLocked(); 2565 23146 } 2566 23147 } 2567 23148 2568 23149 final void setUidTempWhitelistStateLocked(int uid, boolean onWhitelist) { 2569 23150 boolean changed = false; 2570 23151 final UidRecord uidRec = mActiveUids.get(uid); 2571 23152 if (uidRec != null && uidRec.curWhitelist != onWhitelist) { 2572 23153 uidRec.curWhitelist = onWhitelist; 2573 23154 updateOomAdjLocked(); 2574 23155 } 2575 23156 } 2576 23157 2577 23158 final void trimApplications() { 2578 23159 synchronized (this) { 2579 23160 int i; 2580 23161 2581 23162 // First remove any unused application processes whose package 2582 23163 // has been removed. 2583 23164 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 2584 23165 final ProcessRecord app = mRemovedProcesses.get(i); 2585 23166 if (app.activities.size() == 0 2586 23167 && app.curReceivers.isEmpty() && app.services.size() == 0) { 2587 23168 Slog.i( 2588 23169 TAG, "Exiting empty application process " 2589 23170 + app.toShortString() + " (" 2590 23171 + (app.thread != null ? app.thread.asBinder() : null) 2591 23172 + ")\n"); 2592 23173 if (app.pid > 0 && app.pid != MY_PID) { 2593 23174 app.kill("empty", false); 2594 23175 } else { 2595 23176 try { 2596 23177 app.thread.scheduleExit(); 2597 23178 } catch (Exception e) { 2598 23179 // Ignore exceptions. 2599 23180 } 2600 23181 } 2601 23182 cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/); 2602 23183 mRemovedProcesses.remove(i); 2603 23184 2604 23185 if (app.persistent) { 2605 23186 addAppLocked(app.info, null, false, null /* ABI override */); 2606 23187 } 2607 23188 } 2608 23189 } 2609 23190 2610 23191 // Now update the oom adj for all processes. 2611 23192 updateOomAdjLocked(); 2612 23193 } 2613 23194 } 2614 23195 2615 23196 /** This method sends the specified signal to each of the persistent apps */ 2616 23197 public void signalPersistentProcesses(int sig) throws RemoteException { 2617 23198 if (sig != SIGNAL_USR1) { 2618 23199 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 2619 23200 } 2620 23201 2621 23202 synchronized (this) { 2622 23203 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 2623 23204 != PackageManager.PERMISSION_GRANTED) { 2624 23205 throw new SecurityException("Requires permission " 2625 23206 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 2626 23207 } 2627 23208 2628 23209 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 2629 23210 ProcessRecord r = mLruProcesses.get(i); 2630 23211 if (r.thread != null && r.persistent) { 2631 23212 sendSignal(r.pid, sig); 2632 23213 } 2633 23214 } 2634 23215 } 2635 23216 }
profile操作相关
1 23218 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 2 23219 if (proc == null || proc == mProfileProc) { 3 23220 proc = mProfileProc; 4 23221 profileType = mProfileType; 5 23222 clearProfilerLocked(); 6 23223 } 7 23224 if (proc == null) { 8 23225 return; 9 23226 } 10 23227 try { 11 23228 proc.thread.profilerControl(false, null, profileType); 12 23229 } catch (RemoteException e) { 13 23230 throw new IllegalStateException("Process disappeared"); 14 23231 } 15 23232 } 16 23233 17 23234 private void clearProfilerLocked() { 18 23235 if (mProfileFd != null) { 19 23236 try { 20 23237 mProfileFd.close(); 21 23238 } catch (IOException e) { 22 23239 } 23 23240 } 24 23241 mProfileApp = null; 25 23242 mProfileProc = null; 26 23243 mProfileFile = null; 27 23244 mProfileType = 0; 28 23245 mAutoStopProfiler = false; 29 23246 mStreamingOutput = false; 30 23247 mSamplingInterval = 0; 31 23248 } 32 23249 33 23250 public boolean profileControl(String process, int userId, boolean start, 34 23251 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 35 23252 36 23253 try { 37 23254 synchronized (this) { 38 23255 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 39 23256 // its own permission. 40 23257 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 41 23258 != PackageManager.PERMISSION_GRANTED) { 42 23259 throw new SecurityException("Requires permission " 43 23260 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 44 23261 } 45 23262 46 23263 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 47 23264 throw new IllegalArgumentException("null profile info or fd"); 48 23265 } 49 23266 50 23267 ProcessRecord proc = null; 51 23268 if (process != null) { 52 23269 proc = findProcessLocked(process, userId, "profileControl"); 53 23270 } 54 23271 55 23272 if (start && (proc == null || proc.thread == null)) { 56 23273 throw new IllegalArgumentException("Unknown process: " + process); 57 23274 } 58 23275 59 23276 if (start) { 60 23277 stopProfilerLocked(null, 0); 61 23278 setProfileApp(proc.info, proc.processName, profilerInfo); 62 23279 mProfileProc = proc; 63 23280 mProfileType = profileType; 64 23281 ParcelFileDescriptor fd = profilerInfo.profileFd; 65 23282 try { 66 23283 fd = fd.dup(); 67 23284 } catch (IOException e) { 68 23285 fd = null; 69 23286 } 70 23287 profilerInfo.profileFd = fd; 71 23288 proc.thread.profilerControl(start, profilerInfo, profileType); 72 23289 fd = null; 73 23290 try { 74 23291 mProfileFd.close(); 75 23292 } catch (IOException e) { 76 23293 } 77 23294 mProfileFd = null; 78 23295 } else { 79 23296 stopProfilerLocked(proc, profileType); 80 23297 if (profilerInfo != null && profilerInfo.profileFd != null) { 81 23298 try { 82 23299 profilerInfo.profileFd.close(); 83 23300 } catch (IOException e) { 84 23301 } 85 23302 } 86 23303 } 87 23304 88 23305 return true; 89 23306 } 90 23307 } catch (RemoteException e) { 91 23308 throw new IllegalStateException("Process disappeared"); 92 23309 } finally { 93 23310 if (profilerInfo != null && profilerInfo.profileFd != null) { 94 23311 try { 95 23312 profilerInfo.profileFd.close(); 96 23313 } catch (IOException e) { 97 23314 } 98 23315 } 99 23316 } 100 23317 }
找到进程
1 23319 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 2 23320 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 3 23321 userId, true, ALLOW_FULL_ONLY, callName, null); 4 23322 ProcessRecord proc = null; 5 23323 try { 6 23324 int pid = Integer.parseInt(process); 7 23325 synchronized (mPidsSelfLocked) { 8 23326 proc = mPidsSelfLocked.get(pid); 9 23327 } 10 23328 } catch (NumberFormatException e) { 11 23329 } 12 23330 13 23331 if (proc == null) { 14 23332 ArrayMap<String, SparseArray<ProcessRecord>> all 15 23333 = mProcessNames.getMap(); 16 23334 SparseArray<ProcessRecord> procs = all.get(process); 17 23335 if (procs != null && procs.size() > 0) { 18 23336 proc = procs.valueAt(0); 19 23337 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 20 23338 for (int i=1; i<procs.size(); i++) { 21 23339 ProcessRecord thisProc = procs.valueAt(i); 22 23340 if (thisProc.userId == userId) { 23 23341 proc = thisProc; 24 23342 break; 25 23343 } 26 23344 } 27 23345 } 28 23346 } 29 23347 } 30 23348 31 23349 return proc; 32 23350 }
dump heap
1 23352 public boolean dumpHeap(String process, int userId, boolean managed, 2 23353 String path, ParcelFileDescriptor fd) throws RemoteException { 3 23354 4 23355 try { 5 23356 synchronized (this) { 6 23357 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 7 23358 // its own permission (same as profileControl). 8 23359 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9 23360 != PackageManager.PERMISSION_GRANTED) { 10 23361 throw new SecurityException("Requires permission " 11 23362 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 12 23363 } 13 23364 14 23365 if (fd == null) { 15 23366 throw new IllegalArgumentException("null fd"); 16 23367 } 17 23368 18 23369 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 19 23370 if (proc == null || proc.thread == null) { 20 23371 throw new IllegalArgumentException("Unknown process: " + process); 21 23372 } 22 23373 23 23374 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 24 23375 if (!isDebuggable) { 25 23376 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 26 23377 throw new SecurityException("Process not debuggable: " + proc); 27 23378 } 28 23379 } 29 23380 30 23381 proc.thread.dumpHeap(managed, path, fd); 31 23382 fd = null; 32 23383 return true; 33 23384 } 34 23385 } catch (RemoteException e) { 35 23386 throw new IllegalStateException("Process disappeared"); 36 23387 } finally { 37 23388 if (fd != null) { 38 23389 try { 39 23390 fd.close(); 40 23391 } catch (IOException e) { 41 23392 } 42 23393 } 43 23394 } 44 23395 } 45 23396 46 23397 @Override 47 23398 public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize, 48 23399 String reportPackage) { 49 23400 if (processName != null) { 50 23401 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 51 23402 "setDumpHeapDebugLimit()"); 52 23403 } else { 53 23404 synchronized (mPidsSelfLocked) { 54 23405 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid()); 55 23406 if (proc == null) { 56 23407 throw new SecurityException("No process found for calling pid " 57 23408 + Binder.getCallingPid()); 58 23409 } 59 23410 if (!Build.IS_DEBUGGABLE 60 23411 && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 61 23412 throw new SecurityException("Not running a debuggable build"); 62 23413 } 63 23414 processName = proc.processName; 64 23415 uid = proc.uid; 65 23416 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) { 66 23417 throw new SecurityException("Package " + reportPackage + " is not running in " 67 23418 + proc); 68 23419 } 69 23420 } 70 23421 } 71 23422 synchronized (this) { 72 23423 if (maxMemSize > 0) { 73 23424 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage)); 74 23425 } else { 75 23426 if (uid != 0) { 76 23427 mMemWatchProcesses.remove(processName, uid); 77 23428 } else { 78 23429 mMemWatchProcesses.getMap().remove(processName); 79 23430 } 80 23431 } 81 23432 } 82 23433 } 83 23434 84 23435 @Override 85 23436 public void dumpHeapFinished(String path) { 86 23437 synchronized (this) { 87 23438 if (Binder.getCallingPid() != mMemWatchDumpPid) { 88 23439 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid() 89 23440 + " does not match last pid " + mMemWatchDumpPid); 90 23441 return; 91 23442 } 92 23443 if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) { 93 23444 Slog.w(TAG, "dumpHeapFinished: Calling path " + path 94 23445 + " does not match last path " + mMemWatchDumpFile); 95 23446 return; 96 23447 } 97 23448 if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path); 98 23449 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG); 99 23450 } 100 23451 } 101 23452
monitor
1 23453 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 2 23454 public void monitor() { 3 23455 synchronized (this) { } 4 23456 } 5 23457
核心设置改变回调
1 23458 void onCoreSettingsChange(Bundle settings) { 2 23459 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3 23460 ProcessRecord processRecord = mLruProcesses.get(i); 4 23461 try { 5 23462 if (processRecord.thread != null) { 6 23463 processRecord.thread.setCoreSettings(settings); 7 23464 } 8 23465 } catch (RemoteException re) { 9 23466 /* ignore */ 10 23467 } 11 23468
多用户相关
1 23471 // Multi-user methods 2 23472 3 23473 /** 4 23474 * Start user, if its not already running, but don't bring it to foreground. 5 23475 */ 6 23476 @Override 7 23477 public boolean startUserInBackground(final int userId) { 8 23478 return mUserController.startUser(userId, /* foreground */ false); 9 23479 } 10 23480 11 23481 @Override 12 23482 public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) { 13 23483 return mUserController.unlockUser(userId, token, secret, listener); 14 23484 } 15 23485 16 23486 @Override 17 23487 public boolean switchUser(final int targetUserId) { 18 23488 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId); 19 23489 int currentUserId; 20 23490 UserInfo targetUserInfo; 21 23491 synchronized (this) { 22 23492 currentUserId = mUserController.getCurrentUserIdLocked(); 23 23493 targetUserInfo = mUserController.getUserInfo(targetUserId); 24 23494 if (targetUserId == currentUserId) { 25 23495 Slog.i(TAG, "user #" + targetUserId + " is already the current user"); 26 23496 return true; 27 23497 } 28 23498 if (targetUserInfo == null) { 29 23499 Slog.w(TAG, "No user info for user #" + targetUserId); 30 23500 return false; 31 23501 } 32 23502 if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) { 33 23503 Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId 34 23504 + " when device is in demo mode"); 35 23505 return false; 36 23506 } 37 23507 if (!targetUserInfo.supportsSwitchTo()) { 38 23508 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported"); 39 23509 return false; 40 23510 } 41 23511 if (targetUserInfo.isManagedProfile()) { 42 23512 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user"); 43 23513 return false; 44 23514 } 45 23515 mUserController.setTargetUserIdLocked(targetUserId); 46 23516 } 47 23517 if (mUserController.mUserSwitchUiEnabled) { 48 23518 UserInfo currentUserInfo = mUserController.getUserInfo(currentUserId); 49 23519 Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo); 50 23520 mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG); 51 23521 mUiHandler.sendMessage(mHandler.obtainMessage( 52 23522 START_USER_SWITCH_UI_MSG, userNames)); 53 23523 } else { 54 23524 mHandler.removeMessages(START_USER_SWITCH_FG_MSG); 55 23525 mHandler.sendMessage(mHandler.obtainMessage( 56 23526 START_USER_SWITCH_FG_MSG, targetUserId, 0)); 57 23527 } 58 23528 return true; 59 23529 } 60 23530 61 23531 void scheduleStartProfilesLocked() { 62 23532 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 63 23533 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 64 23534 DateUtils.SECOND_IN_MILLIS); 65 23535 } 66 23536 } 67 23537 68 23538 @Override 69 23539 public int stopUser(final int userId, boolean force, final IStopUserCallback callback) { 70 23540 return mUserController.stopUser(userId, force, callback); 71 23541 } 72 23542 73 23543 @Override 74 23544 public UserInfo getCurrentUser() { 75 23545 return mUserController.getCurrentUser(); 76 23546 } 77 23547 78 23548 String getStartedUserState(int userId) { 79 23549 synchronized (this) { 80 23550 final UserState userState = mUserController.getStartedUserStateLocked(userId); 81 23551 return UserState.stateToString(userState.state); 82 23552 } 83 23553 } 84 23554 85 23555 @Override 86 23556 public boolean isUserRunning(int userId, int flags) { 87 23557 if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId()) 88 23558 && checkCallingPermission(INTERACT_ACROSS_USERS) 89 23559 != PackageManager.PERMISSION_GRANTED) { 90 23560 String msg = "Permission Denial: isUserRunning() from pid=" 91 23561 + Binder.getCallingPid() 92 23562 + ", uid=" + Binder.getCallingUid() 93 23563 + " requires " + INTERACT_ACROSS_USERS; 94 23564 Slog.w(TAG, msg); 95 23565 throw new SecurityException(msg); 96 23566 } 97 23567 synchronized (this) { 98 23568 return mUserController.isUserRunningLocked(userId, flags); 99 23569 } 100 23570 } 101 23571 102 23572 @Override 103 23573 public int[] getRunningUserIds() { 104 23574 if (checkCallingPermission(INTERACT_ACROSS_USERS) 105 23575 != PackageManager.PERMISSION_GRANTED) { 106 23576 String msg = "Permission Denial: isUserRunning() from pid=" 107 23577 + Binder.getCallingPid() 108 23578 + ", uid=" + Binder.getCallingUid() 109 23579 + " requires " + INTERACT_ACROSS_USERS; 110 23580 Slog.w(TAG, msg); 111 23581 throw new SecurityException(msg); 112 23582 } 113 23583 synchronized (this) { 114 23584 return mUserController.getStartedUserArrayLocked(); 115 23585 } 116 23586 } 117 23587 118 23588 @Override 119 23589 public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) { 120 23590 mUserController.registerUserSwitchObserver(observer, name); 121 23591 } 122 23592 123 23593 @Override 124 23594 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 125 23595 mUserController.unregisterUserSwitchObserver(observer); 126 23596 } 127 23597 128 23598 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 129 23599 if (info == null) return null; 130 23600 ApplicationInfo newInfo = new ApplicationInfo(info); 131 23601 newInfo.initForUser(userId); 132 23602 return newInfo; 133 23603 } 134 23604 135 23605 public boolean isUserStopped(int userId) { 136 23606 synchronized (this) { 137 23607 return mUserController.getStartedUserStateLocked(userId) == null; 138 23608 } 139 23609 } 140 23610 141 23611 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 142 23612 if (aInfo == null 143 23613 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 144 23614 return aInfo; 145 23615 } 146 23616 147 23617 ActivityInfo info = new ActivityInfo(aInfo); 148 23618 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 149 23619 return info; 150 23620 }
开始、结束bind track
1 23637 public boolean startBinderTracking() throws RemoteException { 2 23638 synchronized (this) { 3 23639 mBinderTransactionTrackingEnabled = true; 4 23640 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own 5 23641 // permission (same as profileControl). 6 23642 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 7 23643 != PackageManager.PERMISSION_GRANTED) { 8 23644 throw new SecurityException("Requires permission " 9 23645 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10 23646 } 11 23647 12 23648 for (int i = 0; i < mLruProcesses.size(); i++) { 13 23649 ProcessRecord process = mLruProcesses.get(i); 14 23650 if (!processSanityChecksLocked(process)) { 15 23651 continue; 16 23652 } 17 23653 try { 18 23654 process.thread.startBinderTracking(); 19 23655 } catch (RemoteException e) { 20 23656 Log.v(TAG, "Process disappared"); 21 23657 } 22 23658 } 23 23659 return true; 24 23660 } 25 23661 } 26 23662 27 23663 public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException { 28 23664 try { 29 23665 synchronized (this) { 30 23666 mBinderTransactionTrackingEnabled = false; 31 23667 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own 32 23668 // permission (same as profileControl). 33 23669 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 34 23670 != PackageManager.PERMISSION_GRANTED) { 35 23671 throw new SecurityException("Requires permission " 36 23672 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 37 23673 } 38 23674 39 23675 if (fd == null) { 40 23676 throw new IllegalArgumentException("null fd"); 41 23677 } 42 23678 43 23679 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor())); 44 23680 pw.println("Binder transaction traces for all processes.\n"); 45 23681 for (ProcessRecord process : mLruProcesses) { 46 23682 if (!processSanityChecksLocked(process)) { 47 23683 continue; 48 23684 } 49 23685 50 23686 pw.println("Traces for process: " + process.processName); 51 23687 pw.flush(); 52 23688 try { 53 23689 TransferPipe tp = new TransferPipe(); 54 23690 try { 55 23691 process.thread.stopBinderTrackingAndDump(tp.getWriteFd()); 56 23692 tp.go(fd.getFileDescriptor()); 57 23693 } finally { 58 23694 tp.kill(); 59 23695 } 60 23696 } catch (IOException e) { 61 23697 pw.println("Failure while dumping IPC traces from " + process + 62 23698 ". Exception: " + e); 63 23699 pw.flush(); 64 23700 } catch (RemoteException e) { 65 23701 pw.println("Got a RemoteException while dumping IPC traces from " + 66 23702 process + ". Exception: " + e); 67 23703 pw.flush(); 68 23704 } 69 23705 } 70 23706 fd = null; 71 23707 return true; 72 23708 } 73 23709 } finally { 74 23710 if (fd != null) { 75 23711 try { 76 23712 fd.close(); 77 23713 } catch (IOException e) { 78 23714 } 79 23715 } 80 23716 } 81 23717 }
内部类LocalService实现了ActivityManagerInternal的方法
1 23719 @VisibleForTesting 2 23720 final class LocalService extends ActivityManagerInternal { 3 23721 @Override 4 23722 public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent, 5 23723 int targetUserId) { 6 23724 synchronized (ActivityManagerService.this) { 7 23725 ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid, 8 23726 targetPkg, intent, null, targetUserId); 9 23727 } 10 23728 } 11 23729 12 23730 @Override 13 23731 public String checkContentProviderAccess(String authority, int userId) { 14 23732 return ActivityManagerService.this.checkContentProviderAccess(authority, userId); 15 23733 } 16 23734 17 23735 @Override 18 23736 public void onWakefulnessChanged(int wakefulness) { 19 23737 ActivityManagerService.this.onWakefulnessChanged(wakefulness); 20 23738 } 21 23739 22 23740 @Override 23 23741 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 24 23742 String processName, String abiOverride, int uid, Runnable crashHandler) { 25 23743 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 26 23744 processName, abiOverride, uid, crashHandler); 27 23745 } 28 23746 29 23747 @Override 30 23748 public SleepToken acquireSleepToken(String tag) { 31 23749 Preconditions.checkNotNull(tag); 32 23750 33 23751 synchronized (ActivityManagerService.this) { 34 23752 SleepTokenImpl token = new SleepTokenImpl(tag); 35 23753 mSleepTokens.add(token); 36 23754 updateSleepIfNeededLocked(); 37 23755 return token; 38 23756 } 39 23757 } 40 23758 41 23759 @Override 42 23760 public ComponentName getHomeActivityForUser(int userId) { 43 23761 synchronized (ActivityManagerService.this) { 44 23762 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId); 45 23763 return homeActivity == null ? null : homeActivity.realActivity; 46 23764 } 47 23765 } 48 23766 49 23767 @Override 50 23768 public void onUserRemoved(int userId) { 51 23769 synchronized (ActivityManagerService.this) { 52 23770 ActivityManagerService.this.onUserStoppedLocked(userId); 53 23771 } 54 23772 } 55 23773 56 23774 @Override 57 23775 public void onLocalVoiceInteractionStarted(IBinder activity, 58 23776 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) { 59 23777 synchronized (ActivityManagerService.this) { 60 23778 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity, 61 23779 voiceSession, voiceInteractor); 62 23780 } 63 23781 } 64 23782 65 23783 @Override 66 23784 public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) { 67 23785 synchronized (ActivityManagerService.this) { 68 23786 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting( 69 23787 reasons, timestamp); 70 23788 } 71 23789 } 72 23790 73 23791 @Override 74 23792 public void notifyAppTransitionFinished() { 75 23793 synchronized (ActivityManagerService.this) { 76 23794 mStackSupervisor.notifyAppTransitionDone(); 77 23795 } 78 23796 } 79 23797 80 23798 @Override 81 23799 public void notifyAppTransitionCancelled() { 82 23800 synchronized (ActivityManagerService.this) { 83 23801 mStackSupervisor.notifyAppTransitionDone(); 84 23802 } 85 23803 } 86 23804 87 23805 @Override 88 23806 public List<IBinder> getTopVisibleActivities() { 89 23807 synchronized (ActivityManagerService.this) { 90 23808 return mStackSupervisor.getTopVisibleActivities(); 91 23809 } 92 23810 } 93 23811 94 23812 @Override 95 23813 public void notifyDockedStackMinimizedChanged(boolean minimized) { 96 23814 synchronized (ActivityManagerService.this) { 97 23815 mStackSupervisor.setDockedStackMinimized(minimized); 98 23816 } 99 23817 } 100 23818 101 23819 @Override 102 23820 public void killForegroundAppsForUser(int userHandle) { 103 23821 synchronized (ActivityManagerService.this) { 104 23822 final ArrayList<ProcessRecord> procs = new ArrayList<>(); 105 23823 final int NP = mProcessNames.getMap().size(); 106 23824 for (int ip = 0; ip < NP; ip++) { 107 23825 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 108 23826 final int NA = apps.size(); 109 23827 for (int ia = 0; ia < NA; ia++) { 110 23828 final ProcessRecord app = apps.valueAt(ia); 111 23829 if (app.persistent) { 112 23830 // We don't kill persistent processes. 113 23831 continue; 114 23832 } 115 23833 if (app.removed) { 116 23834 procs.add(app); 117 23835 } else if (app.userId == userHandle && app.foregroundActivities) { 118 23836 app.removed = true; 119 23837 procs.add(app); 120 23838 } 121 23839 } 122 23840 } 123 23841 124 23842 final int N = procs.size(); 125 23843 for (int i = 0; i < N; i++) { 126 23844 removeProcessLocked(procs.get(i), false, true, "kill all fg"); 127 23845 } 128 23846 } 129 23847 } 130 23848 131 23849 @Override 132 23850 public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken, 133 23851 long duration) { 134 23852 if (!(target instanceof PendingIntentRecord)) { 135 23853 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target); 136 23854 return; 137 23855 } 138 23856 ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration); 139 23857 } 140 23858 141 23859 @Override 142 23860 public void setDeviceIdleWhitelist(int[] appids) { 143 23861 synchronized (ActivityManagerService.this) { 144 23862 mDeviceIdleWhitelist = appids; 145 23863 } 146 23864 } 147 23865 148 23866 @Override 149 23867 public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) { 150 23868 synchronized (ActivityManagerService.this) { 151 23869 mDeviceIdleTempWhitelist = appids; 152 23870 setAppIdTempWhitelistStateLocked(changingAppId, adding); 153 23871 } 154 23872 } 155 23873 156 23874 @Override 157 23875 public void updatePersistentConfigurationForUser(@NonNull Configuration values, 158 23876 int userId) { 159 23877 Preconditions.checkNotNull(values, "Configuration must not be null"); 160 23878 Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported"); 161 23879 synchronized (ActivityManagerService.this) { 162 23880 updateConfigurationLocked(values, null, false, true, userId, 163 23881 false /* deferResume */); 164 23882 } 165 23883 } 166 23884 167 23885 @Override 168 23886 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents, 169 23887 Bundle bOptions) { 170 23888 Preconditions.checkNotNull(intents, "intents"); 171 23889 final String[] resolvedTypes = new String[intents.length]; 172 23890 for (int i = 0; i < intents.length; i++) { 173 23891 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver()); 174 23892 } 175 23893 176 23894 // UID of the package on user userId. 177 23895 // "= 0" is needed because otherwise catch(RemoteException) would make it look like 178 23896 // packageUid may not be initialized. 179 23897 int packageUid = 0; 180 23898 try { 181 23899 packageUid = AppGlobals.getPackageManager().getPackageUid( 182 23900 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId); 183 23901 } catch (RemoteException e) { 184 23902 // Shouldn't happen. 185 23903 } 186 23904 187 23905 synchronized (ActivityManagerService.this) { 188 23906 return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes, 189 23907 /*resultTo*/ null, bOptions, userId); 190 23908 } 191 23909 } 192 23910 193 23911 @Override 194 23912 public int getUidProcessState(int uid) { 195 23913 return getUidState(uid); 196 23914 } 197 23915 198 23916 @Override 199 23917 public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) { 200 23918 synchronized (ActivityManagerService.this) { 201 23919 202 23920 // We might change the visibilities here, so prepare an empty app transition which 203 23921 // might be overridden later if we actually change visibilities. 204 23922 mWindowManager.prepareAppTransition(TRANSIT_NONE, false /* alwaysKeepCurrent */); 205 23923 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); 206 23924 mWindowManager.executeAppTransition(); 207 23925 } 208 23926 if (callback != null) { 209 23927 callback.run(); 210 23928 } 211 23929 } 212 23930 213 23931 @Override 214 23932 public boolean isSystemReady() { 215 23933 // no need to synchronize(this) just to read & return the value 216 23934 return mSystemReady; 217 23935 } 218 23936 219 23937 @Override 220 23938 public void notifyKeyguardTrustedChanged() { 221 23939 synchronized (ActivityManagerService.this) { 222 23940 if (mKeyguardController.isKeyguardShowing()) { 223 23941 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); 224 23942 } 225 23943 } 226 23944 } 227 23945 228 23946 /** 229 23947 * Sets if the given pid has an overlay UI or not. 230 23948 * 231 23949 * @param pid The pid we are setting overlay UI for. 232 23950 * @param hasOverlayUi True if the process has overlay UI. 233 23951 * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY 234 23952 */ 235 23953 @Override 236 23954 public void setHasOverlayUi(int pid, boolean hasOverlayUi) { 237 23955 synchronized (ActivityManagerService.this) { 238 23956 final ProcessRecord pr; 239 23957 synchronized (mPidsSelfLocked) { 240 23958 pr = mPidsSelfLocked.get(pid); 241 23959 if (pr == null) { 242 23960 Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid); 243 23961 return; 244 23962 } 245 23963 } 246 23964 if (pr.hasOverlayUi == hasOverlayUi) { 247 23965 return; 248 23966 } 249 23967 pr.hasOverlayUi = hasOverlayUi; 250 23968 //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid); 251 23969 updateOomAdjLocked(pr, true); 252 23970 } 253 23971 } 254 23972 255 23973 /** 256 23974 * Called after the network policy rules are updated by 257 23975 * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid} 258 23976 * and {@param procStateSeq}. 259 23977 */ 260 23978 @Override 261 23979 public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) { 262 23980 if (DEBUG_NETWORK) { 263 23981 Slog.d(TAG_NETWORK, "Got update from NPMS for uid: " 264 23982 + uid + " seq: " + procStateSeq); 265 23983 } 266 23984 UidRecord record; 267 23985 synchronized (ActivityManagerService.this) { 268 23986 record = mActiveUids.get(uid); 269 23987 if (record == null) { 270 23988 if (DEBUG_NETWORK) { 271 23989 Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid 272 23990 + " procStateSeq: " + procStateSeq); 273 23991 } 274 23992 return; 275 23993 } 276 23994 } 277 23995 synchronized (record.networkStateLock) { 278 23996 if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) { 279 23997 if (DEBUG_NETWORK) { 280 23998 Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already" 281 23999 + " been handled for uid: " + uid); 282 24000 } 283 24001 return; 284 24002 } 285 24003 record.lastNetworkUpdatedProcStateSeq = procStateSeq; 286 24004 if (record.curProcStateSeq > procStateSeq) { 287 24005 if (DEBUG_NETWORK) { 288 24006 Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid 289 24007 + ", curProcstateSeq: " + record.curProcStateSeq 290 24008 + ", procStateSeq: " + procStateSeq); 291 24009 } 292 24010 return; 293 24011 } 294 24012 if (record.waitingForNetwork) { 295 24013 if (DEBUG_NETWORK) { 296 24014 Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid 297 24015 + ", procStateSeq: " + procStateSeq); 298 24016 } 299 24017 record.networkStateLock.notifyAll(); 300 24018 } 301 24019 } 302 24020 }
等待网络状态更新,等待广播idle
1 24069 /** 2 24070 * Called by app main thread to wait for the network policy rules to get updated. 3 24071 * 4 24072 * @param procStateSeq The sequence number indicating the process state change that the main 5 24073 * thread is interested in. 6 24074 */ 7 24075 @Override 8 24076 public void waitForNetworkStateUpdate(long procStateSeq) { 9 24077 final int callingUid = Binder.getCallingUid(); 10 24078 if (DEBUG_NETWORK) { 11 24079 Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq); 12 24080 } 13 24081 UidRecord record; 14 24082 synchronized (this) { 15 24083 record = mActiveUids.get(callingUid); 16 24084 if (record == null) { 17 24085 return; 18 24086 } 19 24087 } 20 24088 synchronized (record.networkStateLock) { 21 24089 if (record.lastDispatchedProcStateSeq < procStateSeq) { 22 24090 if (DEBUG_NETWORK) { 23 24091 Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not " 24 24092 + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid 25 24093 + " lastProcStateSeqDispatchedToObservers: " 26 24094 + record.lastDispatchedProcStateSeq); 27 24095 } 28 24096 return; 29 24097 } 30 24098 if (record.curProcStateSeq > procStateSeq) { 31 24099 if (DEBUG_NETWORK) { 32 24100 Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: " 33 24101 + callingUid + ", curProcStateSeq: " + record.curProcStateSeq 34 24102 + ", procStateSeq: " + procStateSeq); 35 24103 } 36 24104 return; 37 24105 } 38 24106 if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) { 39 24107 if (DEBUG_NETWORK) { 40 24108 Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. " 41 24109 + procStateSeq + ", so no need to wait. Uid: " 42 24110 + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: " 43 24111 + record.lastNetworkUpdatedProcStateSeq); 44 24112 } 45 24113 return; 46 24114 } 47 24115 try { 48 24116 if (DEBUG_NETWORK) { 49 24117 Slog.d(TAG_NETWORK, "Starting to wait for the network rules update." 50 24118 + " Uid: " + callingUid + " procStateSeq: " + procStateSeq); 51 24119 } 52 24120 final long startTime = SystemClock.uptimeMillis(); 53 24121 record.waitingForNetwork = true; 54 24122 record.networkStateLock.wait(mWaitForNetworkTimeoutMs); 55 24123 record.waitingForNetwork = false; 56 24124 final long totalTime = SystemClock.uptimeMillis() - startTime; 57 24125 if (totalTime >= mWaitForNetworkTimeoutMs) { 58 24126 Slog.wtf(TAG_NETWORK, "Total time waited for network rules to get updated: " 59 24127 + totalTime + ". Uid: " + callingUid + " procStateSeq: " 60 24128 + procStateSeq + " UidRec: " + record 61 24129 + " validateUidRec: " + mValidateUids.get(callingUid)); 62 24130 } 63 24131 } catch (InterruptedException e) { 64 24132 Thread.currentThread().interrupt(); 65 24133 } 66 24134 } 67 24135 } 68 24136 69 24137 public void waitForBroadcastIdle(PrintWriter pw) { 70 24138 enforceCallingPermission(permission.DUMP, "waitForBroadcastIdle()"); 71 24139 while (true) { 72 24140 boolean idle = true; 73 24141 synchronized (this) { 74 24142 for (BroadcastQueue queue : mBroadcastQueues) { 75 24143 if (!queue.isIdle()) { 76 24144 final String msg = "Waiting for queue " + queue + " to become idle..."; 77 24145 pw.println(msg); 78 24146 pw.flush(); 79 24147 Slog.v(TAG, msg); 80 24148 idle = false; 81 24149 } 82 24150 } 83 24151 } 84 24152 85 24153 if (idle) { 86 24154 final String msg = "All broadcast queues are idle!"; 87 24155 pw.println(msg); 88 24156 pw.flush(); 89 24157 Slog.v(TAG, msg); 90 24158 return; 91 24159 } else { 92 24160 SystemClock.sleep(1000); 93 24161 } 94 24162 } 95 24163 }
获取上次resumed的activity user id
1 24165 /** 2 24166 * Return the user id of the last resumed activity. 3 24167 */ 4 24168 @Override 5 24169 public @UserIdInt int getLastResumedActivityUserId() { 6 24170 enforceCallingPermission( 7 24171 permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()"); 8 24172 synchronized (this) { 9 24173 if (mLastResumedActivity == null) { 10 24174 return mUserController.getCurrentUserIdLocked(); 11 24175 } 12 24176 return mLastResumedActivity.userId; 13 24177 } 14 24178 } 15 24179
内部类,睡眠token
1 24180 private final class SleepTokenImpl extends SleepToken { 2 24181 private final String mTag; 3 24182 private final long mAcquireTime; 4 24183 5 24184 public SleepTokenImpl(String tag) { 6 24185 mTag = tag; 7 24186 mAcquireTime = SystemClock.uptimeMillis(); 8 24187 } 9 24188 10 24189 @Override 11 24190 public void release() { 12 24191 synchronized (ActivityManagerService.this) { 13 24192 if (mSleepTokens.remove(this)) { 14 24193 updateSleepIfNeededLocked(); 15 24194 } 16 24195 } 17 24196 } 18 24197 19 24198 @Override 20 24199 public String toString() { 21 24200 return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}"; 22 24201 } 23 24202 }
app task实现类
1 24204 /** 2 24205 * An implementation of IAppTask, that allows an app to manage its own tasks via 3 24206 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 4 24207 * only the process that calls getAppTasks() can call the AppTask methods. 5 24208 */ 6 24209 class AppTaskImpl extends IAppTask.Stub { 7 24210 private int mTaskId; 8 24211 private int mCallingUid; 9 24212 10 24213 public AppTaskImpl(int taskId, int callingUid) { 11 24214 mTaskId = taskId; 12 24215 mCallingUid = callingUid; 13 24216 } 14 24217 15 24218 private void checkCaller() { 16 24219 if (mCallingUid != Binder.getCallingUid()) { 17 24220 throw new SecurityException("Caller " + mCallingUid 18 24221 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 19 24222 } 20 24223 } 21 24224 22 24225 @Override 23 24226 public void finishAndRemoveTask() { 24 24227 checkCaller(); 25 24228 26 24229 synchronized (ActivityManagerService.this) { 27 24230 long origId = Binder.clearCallingIdentity(); 28 24231 try { 29 24232 // We remove the task from recents to preserve backwards 30 24233 if (!mStackSupervisor.removeTaskByIdLocked(mTaskId, false, 31 24234 REMOVE_FROM_RECENTS)) { 32 24235 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 33 24236 } 34 24237 } finally { 35 24238 Binder.restoreCallingIdentity(origId); 36 24239 } 37 24240 } 38 24241 } 39 24242 40 24243 @Override 41 24244 public ActivityManager.RecentTaskInfo getTaskInfo() { 42 24245 checkCaller(); 43 24246 44 24247 synchronized (ActivityManagerService.this) { 45 24248 long origId = Binder.clearCallingIdentity(); 46 24249 try { 47 24250 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId); 48 24251 if (tr == null) { 49 24252 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 50 24253 } 51 24254 return createRecentTaskInfoFromTaskRecord(tr); 52 24255 } finally { 53 24256 Binder.restoreCallingIdentity(origId); 54 24257 } 55 24258 } 56 24259 } 57 24260 58 24261 @Override 59 24262 public void moveToFront() { 60 24263 checkCaller(); 61 24264 // Will bring task to front if it already has a root activity. 62 24265 final long origId = Binder.clearCallingIdentity(); 63 24266 try { 64 24267 synchronized (this) { 65 24268 mStackSupervisor.startActivityFromRecentsInner(mTaskId, null); 66 24269 } 67 24270 } finally { 68 24271 Binder.restoreCallingIdentity(origId); 69 24272 } 70 24273 } 71 24274 72 24275 @Override 73 24276 public int startActivity(IBinder whoThread, String callingPackage, 74 24277 Intent intent, String resolvedType, Bundle bOptions) { 75 24278 checkCaller(); 76 24279 77 24280 int callingUser = UserHandle.getCallingUserId(); 78 24281 TaskRecord tr; 79 24282 IApplicationThread appThread; 80 24283 synchronized (ActivityManagerService.this) { 81 24284 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId); 82 24285 if (tr == null) { 83 24286 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 84 24287 } 85 24288 appThread = IApplicationThread.Stub.asInterface(whoThread); 86 24289 if (appThread == null) { 87 24290 throw new IllegalArgumentException("Bad app thread " + appThread); 88 24291 } 89 24292 } 90 24293 return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent, 91 24294 resolvedType, null, null, null, null, 0, 0, null, null, 92 24295 null, bOptions, false, callingUser, null, tr, "AppTaskImpl"); 93 24296 } 94 24297 95 24298 @Override 96 24299 public void setExcludeFromRecents(boolean exclude) { 97 24300 checkCaller(); 98 24301 99 24302 synchronized (ActivityManagerService.this) { 100 24303 long origId = Binder.clearCallingIdentity(); 101 24304 try { 102 24305 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId); 103 24306 if (tr == null) { 104 24307 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 105 24308 } 106 24309 Intent intent = tr.getBaseIntent(); 107 24310 if (exclude) { 108 24311 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 109 24312 } else { 110 24313 intent.setFlags(intent.getFlags() 111 24314 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 112 24315 } 113 24316 } finally { 114 24317 Binder.restoreCallingIdentity(origId); 115 24318 } 116 24319 } 117 24320 } 118 24321 }
杀掉包依赖关系
1 24323 /** 2 24324 * Kill processes for the user with id userId and that depend on the package named packageName 3 24325 */ 4 24326 @Override 5 24327 public void killPackageDependents(String packageName, int userId) { 6 24328 enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()"); 7 24329 if (packageName == null) { 8 24330 throw new NullPointerException( 9 24331 "Cannot kill the dependents of a package without its name."); 10 24332 } 11 24333 12 24334 long callingId = Binder.clearCallingIdentity(); 13 24335 IPackageManager pm = AppGlobals.getPackageManager(); 14 24336 int pkgUid = -1; 15 24337 try { 16 24338 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId); 17 24339 } catch (RemoteException e) { 18 24340 } 19 24341 if (userId != UserHandle.USER_ALL && pkgUid == -1) { 20 24342 throw new IllegalArgumentException( 21 24343 "Cannot kill dependents of non-existing package " + packageName); 22 24344 } 23 24345 try { 24 24346 synchronized(this) { 25 24347 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId, 26 24348 ProcessList.FOREGROUND_APP_ADJ, false, true, true, false, 27 24349 "dep: " + packageName); 28 24350 } 29 24351 } finally { 30 24352 Binder.restoreCallingIdentity(callingId); 31 24353 } 32 24354 }
取消锁屏
1 24356 @Override 2 24357 public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback) 3 24358 throws RemoteException { 4 24359 final long callingId = Binder.clearCallingIdentity(); 5 24360 try { 6 24361 mKeyguardController.dismissKeyguard(token, callback); 7 24362 } finally { 8 24363 Binder.restoreCallingIdentity(callingId); 9 24364 } 10 24365 }
后台重启用户
1 24367 @Override 2 24368 public int restartUserInBackground(final int userId) { 3 24369 return mUserController.restartUser(userId, /* foreground */ false); 4 24370 } 5 24371
调度、更新app info
1 24372 @Override 2 24373 public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) { 3 24374 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 4 24375 "scheduleApplicationInfoChanged()"); 5 24376 6 24377 synchronized (this) { 7 24378 final long origId = Binder.clearCallingIdentity(); 8 24379 try { 9 24380 updateApplicationInfoLocked(packageNames, userId); 10 24381 } finally { 11 24382 Binder.restoreCallingIdentity(origId); 12 24383 } 13 24384 } 14 24385 } 15 24386 16 24387 void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) { 17 24388 final boolean updateFrameworkRes = packagesToUpdate.contains("android"); 18 24389 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 19 24390 final ProcessRecord app = mLruProcesses.get(i); 20 24391 if (app.thread == null) { 21 24392 continue; 22 24393 } 23 24394 24 24395 if (userId != UserHandle.USER_ALL && app.userId != userId) { 25 24396 continue; 26 24397 } 27 24398 28 24399 final int packageCount = app.pkgList.size(); 29 24400 for (int j = 0; j < packageCount; j++) { 30 24401 final String packageName = app.pkgList.keyAt(j); 31 24402 if (updateFrameworkRes || packagesToUpdate.contains(packageName)) { 32 24403 try { 33 24404 final ApplicationInfo ai = AppGlobals.getPackageManager() 34 24405 .getApplicationInfo(packageName, 0 /*flags*/, app.userId); 35 24406 if (ai != null) { 36 24407 app.thread.scheduleApplicationInfoChanged(ai); 37 24408 } 38 24409 } catch (RemoteException e) { 39 24410 Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s", 40 24411 packageName, app)); 41 24412 } 42 24413 } 43 24414 } 44 24415 } 45 24416 }
附加到agent上
1 24418 /** 2 24419 * Attach an agent to the specified process (proces name or PID) 3 24420 */ 4 24421 public void attachAgent(String process, String path) { 5 24422 try { 6 24423 synchronized (this) { 7 24424 ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent"); 8 24425 if (proc == null || proc.thread == null) { 9 24426 throw new IllegalArgumentException("Unknown process: " + process); 10 24427 } 11 24428 12 24429 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 13 24430 if (!isDebuggable) { 14 24431 if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 15 24432 throw new SecurityException("Process not debuggable: " + proc); 16 24433 } 17 24434 } 18 24435 19 24436 proc.thread.attachAgent(path); 20 24437 } 21 24438 } catch (RemoteException e) { 22 24439 throw new IllegalStateException("Process disappeared"); 23 24440 } 24 24441 }
Injector内部类
1 24443 @VisibleForTesting 2 24444 public static class Injector { 3 24445 private NetworkManagementInternal mNmi; 4 24446 5 24447 public Context getContext() { 6 24448 return null; 7 24449 } 8 24450 9 24451 public AppOpsService getAppOpsService(File file, Handler handler) { 10 24452 return new AppOpsService(file, handler); 11 24453 } 12 24454 13 24455 public Handler getUiHandler(ActivityManagerService service) { 14 24456 return service.new UiHandler(); 15 24457 } 16 24458 17 24459 public boolean isNetworkRestrictedForUid(int uid) { 18 24460 if (ensureHasNetworkManagementInternal()) { 19 24461 return mNmi.isNetworkRestrictedForUid(uid); 20 24462 } 21 24463 return false; 22 24464 } 23 24465 24 24466 private boolean ensureHasNetworkManagementInternal() { 25 24467 if (mNmi == null) { 26 24468 mNmi = LocalServices.getService(NetworkManagementInternal.class); 27 24469 } 28 24470 return mNmi != null; 29 24471 } 30 24472 } 31 24473} 32 24474