【8.0.0_r4】AMS分析(十七)(ActivityManagerService.java下)


代码位于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

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM