ActivityManagerService.java revision 61659e5daaea80104d4d0fd567e78b5f757b5df4
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
20import static android.content.pm.PackageManager.PERMISSION_GRANTED;
21import static com.android.internal.util.XmlUtils.readBooleanAttribute;
22import static com.android.internal.util.XmlUtils.readIntAttribute;
23import static com.android.internal.util.XmlUtils.readLongAttribute;
24import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
25import static com.android.internal.util.XmlUtils.writeIntAttribute;
26import static com.android.internal.util.XmlUtils.writeLongAttribute;
27import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
28import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
29import static org.xmlpull.v1.XmlPullParser.START_TAG;
30import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
31
32import android.Manifest;
33import android.app.AppOpsManager;
34import android.app.IActivityContainer;
35import android.app.IActivityContainerCallback;
36import android.app.IAppTask;
37import android.app.admin.DevicePolicyManager;
38import android.appwidget.AppWidgetManager;
39import android.graphics.Rect;
40import android.os.BatteryStats;
41import android.os.PersistableBundle;
42import android.service.voice.IVoiceInteractionSession;
43import android.util.ArrayMap;
44
45import com.android.internal.R;
46import com.android.internal.annotations.GuardedBy;
47import com.android.internal.app.IAppOpsService;
48import com.android.internal.app.IVoiceInteractor;
49import com.android.internal.app.ProcessMap;
50import com.android.internal.app.ProcessStats;
51import com.android.internal.content.PackageMonitor;
52import com.android.internal.os.BackgroundThread;
53import com.android.internal.os.BatteryStatsImpl;
54import com.android.internal.os.ProcessCpuTracker;
55import com.android.internal.os.TransferPipe;
56import com.android.internal.os.Zygote;
57import com.android.internal.util.FastPrintWriter;
58import com.android.internal.util.FastXmlSerializer;
59import com.android.internal.util.MemInfoReader;
60import com.android.internal.util.Preconditions;
61import com.android.server.AppOpsService;
62import com.android.server.AttributeCache;
63import com.android.server.IntentResolver;
64import com.android.server.LocalServices;
65import com.android.server.ServiceThread;
66import com.android.server.SystemService;
67import com.android.server.SystemServiceManager;
68import com.android.server.Watchdog;
69import com.android.server.am.ActivityStack.ActivityState;
70import com.android.server.firewall.IntentFirewall;
71import com.android.server.pm.UserManagerService;
72import com.android.server.wm.AppTransition;
73import com.android.server.wm.WindowManagerService;
74import com.google.android.collect.Lists;
75import com.google.android.collect.Maps;
76
77import libcore.io.IoUtils;
78
79import org.xmlpull.v1.XmlPullParser;
80import org.xmlpull.v1.XmlPullParserException;
81import org.xmlpull.v1.XmlSerializer;
82
83import android.app.Activity;
84import android.app.ActivityManager;
85import android.app.ActivityManager.RunningTaskInfo;
86import android.app.ActivityManager.StackInfo;
87import android.app.ActivityManagerInternal;
88import android.app.ActivityManagerNative;
89import android.app.ActivityOptions;
90import android.app.ActivityThread;
91import android.app.AlertDialog;
92import android.app.AppGlobals;
93import android.app.ApplicationErrorReport;
94import android.app.Dialog;
95import android.app.IActivityController;
96import android.app.IApplicationThread;
97import android.app.IInstrumentationWatcher;
98import android.app.INotificationManager;
99import android.app.IProcessObserver;
100import android.app.IServiceConnection;
101import android.app.IStopUserCallback;
102import android.app.IUiAutomationConnection;
103import android.app.IUserSwitchObserver;
104import android.app.Instrumentation;
105import android.app.Notification;
106import android.app.NotificationManager;
107import android.app.PendingIntent;
108import android.app.backup.IBackupManager;
109import android.content.ActivityNotFoundException;
110import android.content.BroadcastReceiver;
111import android.content.ClipData;
112import android.content.ComponentCallbacks2;
113import android.content.ComponentName;
114import android.content.ContentProvider;
115import android.content.ContentResolver;
116import android.content.Context;
117import android.content.DialogInterface;
118import android.content.IContentProvider;
119import android.content.IIntentReceiver;
120import android.content.IIntentSender;
121import android.content.Intent;
122import android.content.IntentFilter;
123import android.content.IntentSender;
124import android.content.pm.ActivityInfo;
125import android.content.pm.ApplicationInfo;
126import android.content.pm.ConfigurationInfo;
127import android.content.pm.IPackageDataObserver;
128import android.content.pm.IPackageManager;
129import android.content.pm.InstrumentationInfo;
130import android.content.pm.PackageInfo;
131import android.content.pm.PackageManager;
132import android.content.pm.ParceledListSlice;
133import android.content.pm.UserInfo;
134import android.content.pm.PackageManager.NameNotFoundException;
135import android.content.pm.PathPermission;
136import android.content.pm.ProviderInfo;
137import android.content.pm.ResolveInfo;
138import android.content.pm.ServiceInfo;
139import android.content.res.CompatibilityInfo;
140import android.content.res.Configuration;
141import android.net.Proxy;
142import android.net.ProxyInfo;
143import android.net.Uri;
144import android.os.Binder;
145import android.os.Build;
146import android.os.Bundle;
147import android.os.Debug;
148import android.os.DropBoxManager;
149import android.os.Environment;
150import android.os.FactoryTest;
151import android.os.FileObserver;
152import android.os.FileUtils;
153import android.os.Handler;
154import android.os.IBinder;
155import android.os.IPermissionController;
156import android.os.IRemoteCallback;
157import android.os.IUserManager;
158import android.os.Looper;
159import android.os.Message;
160import android.os.Parcel;
161import android.os.ParcelFileDescriptor;
162import android.os.Process;
163import android.os.RemoteCallbackList;
164import android.os.RemoteException;
165import android.os.SELinux;
166import android.os.ServiceManager;
167import android.os.StrictMode;
168import android.os.SystemClock;
169import android.os.SystemProperties;
170import android.os.UpdateLock;
171import android.os.UserHandle;
172import android.provider.Settings;
173import android.text.format.DateUtils;
174import android.text.format.Time;
175import android.util.AtomicFile;
176import android.util.EventLog;
177import android.util.Log;
178import android.util.Pair;
179import android.util.PrintWriterPrinter;
180import android.util.Slog;
181import android.util.SparseArray;
182import android.util.TimeUtils;
183import android.util.Xml;
184import android.view.Gravity;
185import android.view.LayoutInflater;
186import android.view.View;
187import android.view.WindowManager;
188
189import java.io.BufferedInputStream;
190import java.io.BufferedOutputStream;
191import java.io.DataInputStream;
192import java.io.DataOutputStream;
193import java.io.File;
194import java.io.FileDescriptor;
195import java.io.FileInputStream;
196import java.io.FileNotFoundException;
197import java.io.FileOutputStream;
198import java.io.IOException;
199import java.io.InputStreamReader;
200import java.io.PrintWriter;
201import java.io.StringWriter;
202import java.lang.ref.WeakReference;
203import java.util.ArrayList;
204import java.util.Arrays;
205import java.util.Collections;
206import java.util.Comparator;
207import java.util.HashMap;
208import java.util.HashSet;
209import java.util.Iterator;
210import java.util.List;
211import java.util.Locale;
212import java.util.Map;
213import java.util.Set;
214import java.util.concurrent.atomic.AtomicBoolean;
215import java.util.concurrent.atomic.AtomicLong;
216
217public final class ActivityManagerService extends ActivityManagerNative
218        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
219    private static final String USER_DATA_DIR = "/data/user/";
220    static final String TAG = "ActivityManager";
221    static final String TAG_MU = "ActivityManagerServiceMU";
222    static final boolean DEBUG = false;
223    static final boolean localLOGV = DEBUG;
224    static final boolean DEBUG_BACKUP = localLOGV || false;
225    static final boolean DEBUG_BROADCAST = localLOGV || false;
226    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
227    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
228    static final boolean DEBUG_CLEANUP = localLOGV || false;
229    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
230    static final boolean DEBUG_FOCUS = false;
231    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
232    static final boolean DEBUG_MU = localLOGV || false;
233    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
234    static final boolean DEBUG_LRU = localLOGV || false;
235    static final boolean DEBUG_PAUSE = localLOGV || false;
236    static final boolean DEBUG_POWER = localLOGV || false;
237    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
238    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
239    static final boolean DEBUG_PROCESSES = localLOGV || false;
240    static final boolean DEBUG_PROVIDER = localLOGV || false;
241    static final boolean DEBUG_RESULTS = localLOGV || false;
242    static final boolean DEBUG_SERVICE = localLOGV || false;
243    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
244    static final boolean DEBUG_STACK = localLOGV || false;
245    static final boolean DEBUG_SWITCH = localLOGV || false;
246    static final boolean DEBUG_TASKS = localLOGV || false;
247    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
248    static final boolean DEBUG_TRANSITION = localLOGV || false;
249    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
250    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
251    static final boolean DEBUG_VISBILITY = localLOGV || false;
252    static final boolean DEBUG_PSS = localLOGV || false;
253    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
254    static final boolean VALIDATE_TOKENS = false;
255    static final boolean SHOW_ACTIVITY_START_TIME = true;
256
257    // Control over CPU and battery monitoring.
258    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
259    static final boolean MONITOR_CPU_USAGE = true;
260    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
261    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
262    static final boolean MONITOR_THREAD_CPU_USAGE = false;
263
264    // The flags that are set for all calls we make to the package manager.
265    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
266
267    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
268
269    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
270
271    // Maximum number of recent tasks that we can remember.
272    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 100 : 200;
273
274    // Maximum number recent bitmaps to keep in memory.
275    static final int MAX_RECENT_BITMAPS = 5;
276
277    // Amount of time after a call to stopAppSwitches() during which we will
278    // prevent further untrusted switches from happening.
279    static final long APP_SWITCH_DELAY_TIME = 5*1000;
280
281    // How long we wait for a launched process to attach to the activity manager
282    // before we decide it's never going to come up for real.
283    static final int PROC_START_TIMEOUT = 10*1000;
284
285    // How long we wait for a launched process to attach to the activity manager
286    // before we decide it's never going to come up for real, when the process was
287    // started with a wrapper for instrumentation (such as Valgrind) because it
288    // could take much longer than usual.
289    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
290
291    // How long to wait after going idle before forcing apps to GC.
292    static final int GC_TIMEOUT = 5*1000;
293
294    // The minimum amount of time between successive GC requests for a process.
295    static final int GC_MIN_INTERVAL = 60*1000;
296
297    // The minimum amount of time between successive PSS requests for a process.
298    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
299
300    // The minimum amount of time between successive PSS requests for a process
301    // when the request is due to the memory state being lowered.
302    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
303
304    // The rate at which we check for apps using excessive power -- 15 mins.
305    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
306
307    // The minimum sample duration we will allow before deciding we have
308    // enough data on wake locks to start killing things.
309    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
310
311    // The minimum sample duration we will allow before deciding we have
312    // enough data on CPU usage to start killing things.
313    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
314
315    // How long we allow a receiver to run before giving up on it.
316    static final int BROADCAST_FG_TIMEOUT = 10*1000;
317    static final int BROADCAST_BG_TIMEOUT = 60*1000;
318
319    // How long we wait until we timeout on key dispatching.
320    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
321
322    // How long we wait until we timeout on key dispatching during instrumentation.
323    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
324
325    // Amount of time we wait for observers to handle a user switch before
326    // giving up on them and unfreezing the screen.
327    static final int USER_SWITCH_TIMEOUT = 2*1000;
328
329    // Maximum number of users we allow to be running at a time.
330    static final int MAX_RUNNING_USERS = 3;
331
332    // How long to wait in getAssistContextExtras for the activity and foreground services
333    // to respond with the result.
334    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
335
336    // Maximum number of persisted Uri grants a package is allowed
337    static final int MAX_PERSISTED_URI_GRANTS = 128;
338
339    static final int MY_PID = Process.myPid();
340
341    static final String[] EMPTY_STRING_ARRAY = new String[0];
342
343    // How many bytes to write into the dropbox log before truncating
344    static final int DROPBOX_MAX_SIZE = 256 * 1024;
345
346    /** All system services */
347    SystemServiceManager mSystemServiceManager;
348
349    /** Run all ActivityStacks through this */
350    ActivityStackSupervisor mStackSupervisor;
351
352    public IntentFirewall mIntentFirewall;
353
354    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
355    // default actuion automatically.  Important for devices without direct input
356    // devices.
357    private boolean mShowDialogs = true;
358
359    /**
360     * Description of a request to start a new activity, which has been held
361     * due to app switches being disabled.
362     */
363    static class PendingActivityLaunch {
364        final ActivityRecord r;
365        final ActivityRecord sourceRecord;
366        final int startFlags;
367        final ActivityStack stack;
368
369        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
370                int _startFlags, ActivityStack _stack) {
371            r = _r;
372            sourceRecord = _sourceRecord;
373            startFlags = _startFlags;
374            stack = _stack;
375        }
376    }
377
378    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
379            = new ArrayList<PendingActivityLaunch>();
380
381    BroadcastQueue mFgBroadcastQueue;
382    BroadcastQueue mBgBroadcastQueue;
383    // Convenient for easy iteration over the queues. Foreground is first
384    // so that dispatch of foreground broadcasts gets precedence.
385    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
386
387    BroadcastQueue broadcastQueueForIntent(Intent intent) {
388        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
389        if (DEBUG_BACKGROUND_BROADCAST) {
390            Slog.i(TAG, "Broadcast intent " + intent + " on "
391                    + (isFg ? "foreground" : "background")
392                    + " queue");
393        }
394        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
395    }
396
397    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
398        for (BroadcastQueue queue : mBroadcastQueues) {
399            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
400            if (r != null) {
401                return r;
402            }
403        }
404        return null;
405    }
406
407    /**
408     * Activity we have told the window manager to have key focus.
409     */
410    ActivityRecord mFocusedActivity = null;
411
412    /**
413     * List of intents that were used to start the most recent tasks.
414     */
415    ArrayList<TaskRecord> mRecentTasks;
416
417    public class PendingAssistExtras extends Binder implements Runnable {
418        public final ActivityRecord activity;
419        public boolean haveResult = false;
420        public Bundle result = null;
421        public PendingAssistExtras(ActivityRecord _activity) {
422            activity = _activity;
423        }
424        @Override
425        public void run() {
426            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
427            synchronized (this) {
428                haveResult = true;
429                notifyAll();
430            }
431        }
432    }
433
434    final ArrayList<PendingAssistExtras> mPendingAssistExtras
435            = new ArrayList<PendingAssistExtras>();
436
437    /**
438     * Process management.
439     */
440    final ProcessList mProcessList = new ProcessList();
441
442    /**
443     * All of the applications we currently have running organized by name.
444     * The keys are strings of the application package name (as
445     * returned by the package manager), and the keys are ApplicationRecord
446     * objects.
447     */
448    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
449
450    /**
451     * Tracking long-term execution of processes to look for abuse and other
452     * bad app behavior.
453     */
454    final ProcessStatsService mProcessStats;
455
456    /**
457     * The currently running isolated processes.
458     */
459    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
460
461    /**
462     * Counter for assigning isolated process uids, to avoid frequently reusing the
463     * same ones.
464     */
465    int mNextIsolatedProcessUid = 0;
466
467    /**
468     * The currently running heavy-weight process, if any.
469     */
470    ProcessRecord mHeavyWeightProcess = null;
471
472    /**
473     * The last time that various processes have crashed.
474     */
475    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
476
477    /**
478     * Information about a process that is currently marked as bad.
479     */
480    static final class BadProcessInfo {
481        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
482            this.time = time;
483            this.shortMsg = shortMsg;
484            this.longMsg = longMsg;
485            this.stack = stack;
486        }
487
488        final long time;
489        final String shortMsg;
490        final String longMsg;
491        final String stack;
492    }
493
494    /**
495     * Set of applications that we consider to be bad, and will reject
496     * incoming broadcasts from (which the user has no control over).
497     * Processes are added to this set when they have crashed twice within
498     * a minimum amount of time; they are removed from it when they are
499     * later restarted (hopefully due to some user action).  The value is the
500     * time it was added to the list.
501     */
502    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
503
504    /**
505     * All of the processes we currently have running organized by pid.
506     * The keys are the pid running the application.
507     *
508     * <p>NOTE: This object is protected by its own lock, NOT the global
509     * activity manager lock!
510     */
511    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
512
513    /**
514     * All of the processes that have been forced to be foreground.  The key
515     * is the pid of the caller who requested it (we hold a death
516     * link on it).
517     */
518    abstract class ForegroundToken implements IBinder.DeathRecipient {
519        int pid;
520        IBinder token;
521    }
522    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
523
524    /**
525     * List of records for processes that someone had tried to start before the
526     * system was ready.  We don't start them at that point, but ensure they
527     * are started by the time booting is complete.
528     */
529    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
530
531    /**
532     * List of persistent applications that are in the process
533     * of being started.
534     */
535    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
536
537    /**
538     * Processes that are being forcibly torn down.
539     */
540    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
541
542    /**
543     * List of running applications, sorted by recent usage.
544     * The first entry in the list is the least recently used.
545     */
546    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
547
548    /**
549     * Where in mLruProcesses that the processes hosting activities start.
550     */
551    int mLruProcessActivityStart = 0;
552
553    /**
554     * Where in mLruProcesses that the processes hosting services start.
555     * This is after (lower index) than mLruProcessesActivityStart.
556     */
557    int mLruProcessServiceStart = 0;
558
559    /**
560     * List of processes that should gc as soon as things are idle.
561     */
562    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
563
564    /**
565     * Processes we want to collect PSS data from.
566     */
567    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
568
569    /**
570     * Last time we requested PSS data of all processes.
571     */
572    long mLastFullPssTime = SystemClock.uptimeMillis();
573
574    /**
575     * If set, the next time we collect PSS data we should do a full collection
576     * with data from native processes and the kernel.
577     */
578    boolean mFullPssPending = false;
579
580    /**
581     * This is the process holding what we currently consider to be
582     * the "home" activity.
583     */
584    ProcessRecord mHomeProcess;
585
586    /**
587     * This is the process holding the activity the user last visited that
588     * is in a different process from the one they are currently in.
589     */
590    ProcessRecord mPreviousProcess;
591
592    /**
593     * The time at which the previous process was last visible.
594     */
595    long mPreviousProcessVisibleTime;
596
597    /**
598     * Which uses have been started, so are allowed to run code.
599     */
600    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
601
602    /**
603     * LRU list of history of current users.  Most recently current is at the end.
604     */
605    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
606
607    /**
608     * Constant array of the users that are currently started.
609     */
610    int[] mStartedUserArray = new int[] { 0 };
611
612    /**
613     * Registered observers of the user switching mechanics.
614     */
615    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
616            = new RemoteCallbackList<IUserSwitchObserver>();
617
618    /**
619     * Currently active user switch.
620     */
621    Object mCurUserSwitchCallback;
622
623    /**
624     * Packages that the user has asked to have run in screen size
625     * compatibility mode instead of filling the screen.
626     */
627    final CompatModePackages mCompatModePackages;
628
629    /**
630     * Set of IntentSenderRecord objects that are currently active.
631     */
632    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
633            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
634
635    /**
636     * Fingerprints (hashCode()) of stack traces that we've
637     * already logged DropBox entries for.  Guarded by itself.  If
638     * something (rogue user app) forces this over
639     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
640     */
641    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
642    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
643
644    /**
645     * Strict Mode background batched logging state.
646     *
647     * The string buffer is guarded by itself, and its lock is also
648     * used to determine if another batched write is already
649     * in-flight.
650     */
651    private final StringBuilder mStrictModeBuffer = new StringBuilder();
652
653    /**
654     * Keeps track of all IIntentReceivers that have been registered for
655     * broadcasts.  Hash keys are the receiver IBinder, hash value is
656     * a ReceiverList.
657     */
658    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
659            new HashMap<IBinder, ReceiverList>();
660
661    /**
662     * Resolver for broadcast intents to registered receivers.
663     * Holds BroadcastFilter (subclass of IntentFilter).
664     */
665    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
666            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
667        @Override
668        protected boolean allowFilterResult(
669                BroadcastFilter filter, List<BroadcastFilter> dest) {
670            IBinder target = filter.receiverList.receiver.asBinder();
671            for (int i=dest.size()-1; i>=0; i--) {
672                if (dest.get(i).receiverList.receiver.asBinder() == target) {
673                    return false;
674                }
675            }
676            return true;
677        }
678
679        @Override
680        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
681            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
682                    || userId == filter.owningUserId) {
683                return super.newResult(filter, match, userId);
684            }
685            return null;
686        }
687
688        @Override
689        protected BroadcastFilter[] newArray(int size) {
690            return new BroadcastFilter[size];
691        }
692
693        @Override
694        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
695            return packageName.equals(filter.packageName);
696        }
697    };
698
699    /**
700     * State of all active sticky broadcasts per user.  Keys are the action of the
701     * sticky Intent, values are an ArrayList of all broadcasted intents with
702     * that action (which should usually be one).  The SparseArray is keyed
703     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
704     * for stickies that are sent to all users.
705     */
706    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
707            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
708
709    final ActiveServices mServices;
710
711    /**
712     * Backup/restore process management
713     */
714    String mBackupAppName = null;
715    BackupRecord mBackupTarget = null;
716
717    final ProviderMap mProviderMap;
718
719    /**
720     * List of content providers who have clients waiting for them.  The
721     * application is currently being launched and the provider will be
722     * removed from this list once it is published.
723     */
724    final ArrayList<ContentProviderRecord> mLaunchingProviders
725            = new ArrayList<ContentProviderRecord>();
726
727    /**
728     * File storing persisted {@link #mGrantedUriPermissions}.
729     */
730    private final AtomicFile mGrantFile;
731
732    /** XML constants used in {@link #mGrantFile} */
733    private static final String TAG_URI_GRANTS = "uri-grants";
734    private static final String TAG_URI_GRANT = "uri-grant";
735    private static final String ATTR_USER_HANDLE = "userHandle";
736    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
737    private static final String ATTR_TARGET_USER_ID = "targetUserId";
738    private static final String ATTR_SOURCE_PKG = "sourcePkg";
739    private static final String ATTR_TARGET_PKG = "targetPkg";
740    private static final String ATTR_URI = "uri";
741    private static final String ATTR_MODE_FLAGS = "modeFlags";
742    private static final String ATTR_CREATED_TIME = "createdTime";
743    private static final String ATTR_PREFIX = "prefix";
744
745    /**
746     * Global set of specific {@link Uri} permissions that have been granted.
747     * This optimized lookup structure maps from {@link UriPermission#targetUid}
748     * to {@link UriPermission#uri} to {@link UriPermission}.
749     */
750    @GuardedBy("this")
751    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
752            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
753
754    public static class GrantUri {
755        public final int sourceUserId;
756        public final Uri uri;
757        public boolean prefix;
758
759        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
760            this.sourceUserId = sourceUserId;
761            this.uri = uri;
762            this.prefix = prefix;
763        }
764
765        @Override
766        public int hashCode() {
767            return toString().hashCode();
768        }
769
770        @Override
771        public boolean equals(Object o) {
772            if (o instanceof GrantUri) {
773                GrantUri other = (GrantUri) o;
774                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
775                        && prefix == other.prefix;
776            }
777            return false;
778        }
779
780        @Override
781        public String toString() {
782            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
783            if (prefix) result += " [prefix]";
784            return result;
785        }
786
787        public String toSafeString() {
788            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
789            if (prefix) result += " [prefix]";
790            return result;
791        }
792
793        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
794            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
795                    ContentProvider.getUriWithoutUserId(uri), false);
796        }
797    }
798
799    CoreSettingsObserver mCoreSettingsObserver;
800
801    /**
802     * Thread-local storage used to carry caller permissions over through
803     * indirect content-provider access.
804     */
805    private class Identity {
806        public int pid;
807        public int uid;
808
809        Identity(int _pid, int _uid) {
810            pid = _pid;
811            uid = _uid;
812        }
813    }
814
815    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
816
817    /**
818     * All information we have collected about the runtime performance of
819     * any user id that can impact battery performance.
820     */
821    final BatteryStatsService mBatteryStatsService;
822
823    /**
824     * Information about component usage
825     */
826    final UsageStatsService mUsageStatsService;
827
828    /**
829     * Information about and control over application operations
830     */
831    final AppOpsService mAppOpsService;
832
833    /**
834     * Save recent tasks information across reboots.
835     */
836    final TaskPersister mTaskPersister;
837
838    /**
839     * Current configuration information.  HistoryRecord objects are given
840     * a reference to this object to indicate which configuration they are
841     * currently running in, so this object must be kept immutable.
842     */
843    Configuration mConfiguration = new Configuration();
844
845    /**
846     * Current sequencing integer of the configuration, for skipping old
847     * configurations.
848     */
849    int mConfigurationSeq = 0;
850
851    /**
852     * Hardware-reported OpenGLES version.
853     */
854    final int GL_ES_VERSION;
855
856    /**
857     * List of initialization arguments to pass to all processes when binding applications to them.
858     * For example, references to the commonly used services.
859     */
860    HashMap<String, IBinder> mAppBindArgs;
861
862    /**
863     * Temporary to avoid allocations.  Protected by main lock.
864     */
865    final StringBuilder mStringBuilder = new StringBuilder(256);
866
867    /**
868     * Used to control how we initialize the service.
869     */
870    ComponentName mTopComponent;
871    String mTopAction = Intent.ACTION_MAIN;
872    String mTopData;
873    boolean mProcessesReady = false;
874    boolean mSystemReady = false;
875    boolean mBooting = false;
876    boolean mWaitingUpdate = false;
877    boolean mDidUpdate = false;
878    boolean mOnBattery = false;
879    boolean mLaunchWarningShown = false;
880
881    Context mContext;
882
883    int mFactoryTest;
884
885    boolean mCheckedForSetup;
886
887    /**
888     * The time at which we will allow normal application switches again,
889     * after a call to {@link #stopAppSwitches()}.
890     */
891    long mAppSwitchesAllowedTime;
892
893    /**
894     * This is set to true after the first switch after mAppSwitchesAllowedTime
895     * is set; any switches after that will clear the time.
896     */
897    boolean mDidAppSwitch;
898
899    /**
900     * Last time (in realtime) at which we checked for power usage.
901     */
902    long mLastPowerCheckRealtime;
903
904    /**
905     * Last time (in uptime) at which we checked for power usage.
906     */
907    long mLastPowerCheckUptime;
908
909    /**
910     * Set while we are wanting to sleep, to prevent any
911     * activities from being started/resumed.
912     */
913    private boolean mSleeping = false;
914
915    /**
916     * Set while we are running a voice interaction.  This overrides
917     * sleeping while it is active.
918     */
919    private boolean mRunningVoice = false;
920
921    /**
922     * State of external calls telling us if the device is asleep.
923     */
924    private boolean mWentToSleep = false;
925
926    /**
927     * State of external call telling us if the lock screen is shown.
928     */
929    private boolean mLockScreenShown = false;
930
931    /**
932     * Set if we are shutting down the system, similar to sleeping.
933     */
934    boolean mShuttingDown = false;
935
936    /**
937     * Current sequence id for oom_adj computation traversal.
938     */
939    int mAdjSeq = 0;
940
941    /**
942     * Current sequence id for process LRU updating.
943     */
944    int mLruSeq = 0;
945
946    /**
947     * Keep track of the non-cached/empty process we last found, to help
948     * determine how to distribute cached/empty processes next time.
949     */
950    int mNumNonCachedProcs = 0;
951
952    /**
953     * Keep track of the number of cached hidden procs, to balance oom adj
954     * distribution between those and empty procs.
955     */
956    int mNumCachedHiddenProcs = 0;
957
958    /**
959     * Keep track of the number of service processes we last found, to
960     * determine on the next iteration which should be B services.
961     */
962    int mNumServiceProcs = 0;
963    int mNewNumAServiceProcs = 0;
964    int mNewNumServiceProcs = 0;
965
966    /**
967     * Allow the current computed overall memory level of the system to go down?
968     * This is set to false when we are killing processes for reasons other than
969     * memory management, so that the now smaller process list will not be taken as
970     * an indication that memory is tighter.
971     */
972    boolean mAllowLowerMemLevel = false;
973
974    /**
975     * The last computed memory level, for holding when we are in a state that
976     * processes are going away for other reasons.
977     */
978    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
979
980    /**
981     * The last total number of process we have, to determine if changes actually look
982     * like a shrinking number of process due to lower RAM.
983     */
984    int mLastNumProcesses;
985
986    /**
987     * The uptime of the last time we performed idle maintenance.
988     */
989    long mLastIdleTime = SystemClock.uptimeMillis();
990
991    /**
992     * Total time spent with RAM that has been added in the past since the last idle time.
993     */
994    long mLowRamTimeSinceLastIdle = 0;
995
996    /**
997     * If RAM is currently low, when that horrible situation started.
998     */
999    long mLowRamStartTime = 0;
1000
1001    /**
1002     * For reporting to battery stats the current top application.
1003     */
1004    private String mCurResumedPackage = null;
1005    private int mCurResumedUid = -1;
1006
1007    /**
1008     * For reporting to battery stats the apps currently running foreground
1009     * service.  The ProcessMap is package/uid tuples; each of these contain
1010     * an array of the currently foreground processes.
1011     */
1012    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1013            = new ProcessMap<ArrayList<ProcessRecord>>();
1014
1015    /**
1016     * This is set if we had to do a delayed dexopt of an app before launching
1017     * it, to increase the ANR timeouts in that case.
1018     */
1019    boolean mDidDexOpt;
1020
1021    /**
1022     * Set if the systemServer made a call to enterSafeMode.
1023     */
1024    boolean mSafeMode;
1025
1026    String mDebugApp = null;
1027    boolean mWaitForDebugger = false;
1028    boolean mDebugTransient = false;
1029    String mOrigDebugApp = null;
1030    boolean mOrigWaitForDebugger = false;
1031    boolean mAlwaysFinishActivities = false;
1032    IActivityController mController = null;
1033    String mProfileApp = null;
1034    ProcessRecord mProfileProc = null;
1035    String mProfileFile;
1036    ParcelFileDescriptor mProfileFd;
1037    int mProfileType = 0;
1038    boolean mAutoStopProfiler = false;
1039    String mOpenGlTraceApp = null;
1040
1041    static class ProcessChangeItem {
1042        static final int CHANGE_ACTIVITIES = 1<<0;
1043        static final int CHANGE_PROCESS_STATE = 1<<1;
1044        int changes;
1045        int uid;
1046        int pid;
1047        int processState;
1048        boolean foregroundActivities;
1049    }
1050
1051    final RemoteCallbackList<IProcessObserver> mProcessObservers
1052            = new RemoteCallbackList<IProcessObserver>();
1053    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1054
1055    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1056            = new ArrayList<ProcessChangeItem>();
1057    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1058            = new ArrayList<ProcessChangeItem>();
1059
1060    /**
1061     * Runtime CPU use collection thread.  This object's lock is used to
1062     * protect all related state.
1063     */
1064    final Thread mProcessCpuThread;
1065
1066    /**
1067     * Used to collect process stats when showing not responding dialog.
1068     * Protected by mProcessCpuThread.
1069     */
1070    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1071            MONITOR_THREAD_CPU_USAGE);
1072    final AtomicLong mLastCpuTime = new AtomicLong(0);
1073    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1074
1075    long mLastWriteTime = 0;
1076
1077    /**
1078     * Used to retain an update lock when the foreground activity is in
1079     * immersive mode.
1080     */
1081    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1082
1083    /**
1084     * Set to true after the system has finished booting.
1085     */
1086    boolean mBooted = false;
1087
1088    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1089    int mProcessLimitOverride = -1;
1090
1091    WindowManagerService mWindowManager;
1092
1093    final ActivityThread mSystemThread;
1094
1095    int mCurrentUserId = 0;
1096    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1097    private UserManagerService mUserManager;
1098
1099    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1100        final ProcessRecord mApp;
1101        final int mPid;
1102        final IApplicationThread mAppThread;
1103
1104        AppDeathRecipient(ProcessRecord app, int pid,
1105                IApplicationThread thread) {
1106            if (localLOGV) Slog.v(
1107                TAG, "New death recipient " + this
1108                + " for thread " + thread.asBinder());
1109            mApp = app;
1110            mPid = pid;
1111            mAppThread = thread;
1112        }
1113
1114        @Override
1115        public void binderDied() {
1116            if (localLOGV) Slog.v(
1117                TAG, "Death received in " + this
1118                + " for thread " + mAppThread.asBinder());
1119            synchronized(ActivityManagerService.this) {
1120                appDiedLocked(mApp, mPid, mAppThread);
1121            }
1122        }
1123    }
1124
1125    static final int SHOW_ERROR_MSG = 1;
1126    static final int SHOW_NOT_RESPONDING_MSG = 2;
1127    static final int SHOW_FACTORY_ERROR_MSG = 3;
1128    static final int UPDATE_CONFIGURATION_MSG = 4;
1129    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1130    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1131    static final int SERVICE_TIMEOUT_MSG = 12;
1132    static final int UPDATE_TIME_ZONE = 13;
1133    static final int SHOW_UID_ERROR_MSG = 14;
1134    static final int IM_FEELING_LUCKY_MSG = 15;
1135    static final int PROC_START_TIMEOUT_MSG = 20;
1136    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1137    static final int KILL_APPLICATION_MSG = 22;
1138    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1139    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1140    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1141    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1142    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1143    static final int CLEAR_DNS_CACHE_MSG = 28;
1144    static final int UPDATE_HTTP_PROXY_MSG = 29;
1145    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1146    static final int DISPATCH_PROCESSES_CHANGED = 31;
1147    static final int DISPATCH_PROCESS_DIED = 32;
1148    static final int REPORT_MEM_USAGE_MSG = 33;
1149    static final int REPORT_USER_SWITCH_MSG = 34;
1150    static final int CONTINUE_USER_SWITCH_MSG = 35;
1151    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1152    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1153    static final int PERSIST_URI_GRANTS_MSG = 38;
1154    static final int REQUEST_ALL_PSS_MSG = 39;
1155    static final int START_PROFILES_MSG = 40;
1156    static final int UPDATE_TIME = 41;
1157    static final int SYSTEM_USER_START_MSG = 42;
1158    static final int SYSTEM_USER_CURRENT_MSG = 43;
1159
1160    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1161    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1162    static final int FIRST_COMPAT_MODE_MSG = 300;
1163    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1164
1165    AlertDialog mUidAlert;
1166    CompatModeDialog mCompatModeDialog;
1167    long mLastMemUsageReportTime = 0;
1168
1169    private LockToAppRequestDialog mLockToAppRequest;
1170
1171    /**
1172     * Flag whether the current user is a "monkey", i.e. whether
1173     * the UI is driven by a UI automation tool.
1174     */
1175    private boolean mUserIsMonkey;
1176
1177    final ServiceThread mHandlerThread;
1178    final MainHandler mHandler;
1179
1180    final class MainHandler extends Handler {
1181        public MainHandler(Looper looper) {
1182            super(looper, null, true);
1183        }
1184
1185        @Override
1186        public void handleMessage(Message msg) {
1187            switch (msg.what) {
1188            case SHOW_ERROR_MSG: {
1189                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1190                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1191                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1192                synchronized (ActivityManagerService.this) {
1193                    ProcessRecord proc = (ProcessRecord)data.get("app");
1194                    AppErrorResult res = (AppErrorResult) data.get("result");
1195                    if (proc != null && proc.crashDialog != null) {
1196                        Slog.e(TAG, "App already has crash dialog: " + proc);
1197                        if (res != null) {
1198                            res.set(0);
1199                        }
1200                        return;
1201                    }
1202                    if (!showBackground && UserHandle.getAppId(proc.uid)
1203                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1204                            && proc.pid != MY_PID) {
1205                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1206                        if (res != null) {
1207                            res.set(0);
1208                        }
1209                        return;
1210                    }
1211                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1212                        Dialog d = new AppErrorDialog(mContext,
1213                                ActivityManagerService.this, res, proc);
1214                        d.show();
1215                        proc.crashDialog = d;
1216                    } else {
1217                        // The device is asleep, so just pretend that the user
1218                        // saw a crash dialog and hit "force quit".
1219                        if (res != null) {
1220                            res.set(0);
1221                        }
1222                    }
1223                }
1224
1225                ensureBootCompleted();
1226            } break;
1227            case SHOW_NOT_RESPONDING_MSG: {
1228                synchronized (ActivityManagerService.this) {
1229                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1230                    ProcessRecord proc = (ProcessRecord)data.get("app");
1231                    if (proc != null && proc.anrDialog != null) {
1232                        Slog.e(TAG, "App already has anr dialog: " + proc);
1233                        return;
1234                    }
1235
1236                    Intent intent = new Intent("android.intent.action.ANR");
1237                    if (!mProcessesReady) {
1238                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1239                                | Intent.FLAG_RECEIVER_FOREGROUND);
1240                    }
1241                    broadcastIntentLocked(null, null, intent,
1242                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1243                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1244
1245                    if (mShowDialogs) {
1246                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1247                                mContext, proc, (ActivityRecord)data.get("activity"),
1248                                msg.arg1 != 0);
1249                        d.show();
1250                        proc.anrDialog = d;
1251                    } else {
1252                        // Just kill the app if there is no dialog to be shown.
1253                        killAppAtUsersRequest(proc, null);
1254                    }
1255                }
1256
1257                ensureBootCompleted();
1258            } break;
1259            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1260                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1261                synchronized (ActivityManagerService.this) {
1262                    ProcessRecord proc = (ProcessRecord) data.get("app");
1263                    if (proc == null) {
1264                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1265                        break;
1266                    }
1267                    if (proc.crashDialog != null) {
1268                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1269                        return;
1270                    }
1271                    AppErrorResult res = (AppErrorResult) data.get("result");
1272                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1273                        Dialog d = new StrictModeViolationDialog(mContext,
1274                                ActivityManagerService.this, res, proc);
1275                        d.show();
1276                        proc.crashDialog = d;
1277                    } else {
1278                        // The device is asleep, so just pretend that the user
1279                        // saw a crash dialog and hit "force quit".
1280                        res.set(0);
1281                    }
1282                }
1283                ensureBootCompleted();
1284            } break;
1285            case SHOW_FACTORY_ERROR_MSG: {
1286                Dialog d = new FactoryErrorDialog(
1287                    mContext, msg.getData().getCharSequence("msg"));
1288                d.show();
1289                ensureBootCompleted();
1290            } break;
1291            case UPDATE_CONFIGURATION_MSG: {
1292                final ContentResolver resolver = mContext.getContentResolver();
1293                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1294            } break;
1295            case GC_BACKGROUND_PROCESSES_MSG: {
1296                synchronized (ActivityManagerService.this) {
1297                    performAppGcsIfAppropriateLocked();
1298                }
1299            } break;
1300            case WAIT_FOR_DEBUGGER_MSG: {
1301                synchronized (ActivityManagerService.this) {
1302                    ProcessRecord app = (ProcessRecord)msg.obj;
1303                    if (msg.arg1 != 0) {
1304                        if (!app.waitedForDebugger) {
1305                            Dialog d = new AppWaitingForDebuggerDialog(
1306                                    ActivityManagerService.this,
1307                                    mContext, app);
1308                            app.waitDialog = d;
1309                            app.waitedForDebugger = true;
1310                            d.show();
1311                        }
1312                    } else {
1313                        if (app.waitDialog != null) {
1314                            app.waitDialog.dismiss();
1315                            app.waitDialog = null;
1316                        }
1317                    }
1318                }
1319            } break;
1320            case SERVICE_TIMEOUT_MSG: {
1321                if (mDidDexOpt) {
1322                    mDidDexOpt = false;
1323                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1324                    nmsg.obj = msg.obj;
1325                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1326                    return;
1327                }
1328                mServices.serviceTimeout((ProcessRecord)msg.obj);
1329            } break;
1330            case UPDATE_TIME_ZONE: {
1331                synchronized (ActivityManagerService.this) {
1332                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1333                        ProcessRecord r = mLruProcesses.get(i);
1334                        if (r.thread != null) {
1335                            try {
1336                                r.thread.updateTimeZone();
1337                            } catch (RemoteException ex) {
1338                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1339                            }
1340                        }
1341                    }
1342                }
1343            } break;
1344            case CLEAR_DNS_CACHE_MSG: {
1345                synchronized (ActivityManagerService.this) {
1346                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1347                        ProcessRecord r = mLruProcesses.get(i);
1348                        if (r.thread != null) {
1349                            try {
1350                                r.thread.clearDnsCache();
1351                            } catch (RemoteException ex) {
1352                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1353                            }
1354                        }
1355                    }
1356                }
1357            } break;
1358            case UPDATE_HTTP_PROXY_MSG: {
1359                ProxyInfo proxy = (ProxyInfo)msg.obj;
1360                String host = "";
1361                String port = "";
1362                String exclList = "";
1363                Uri pacFileUrl = Uri.EMPTY;
1364                if (proxy != null) {
1365                    host = proxy.getHost();
1366                    port = Integer.toString(proxy.getPort());
1367                    exclList = proxy.getExclusionListAsString();
1368                    pacFileUrl = proxy.getPacFileUrl();
1369                }
1370                synchronized (ActivityManagerService.this) {
1371                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1372                        ProcessRecord r = mLruProcesses.get(i);
1373                        if (r.thread != null) {
1374                            try {
1375                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1376                            } catch (RemoteException ex) {
1377                                Slog.w(TAG, "Failed to update http proxy for: " +
1378                                        r.info.processName);
1379                            }
1380                        }
1381                    }
1382                }
1383            } break;
1384            case SHOW_UID_ERROR_MSG: {
1385                String title = "System UIDs Inconsistent";
1386                String text = "UIDs on the system are inconsistent, you need to wipe your"
1387                        + " data partition or your device will be unstable.";
1388                Log.e(TAG, title + ": " + text);
1389                if (mShowDialogs) {
1390                    // XXX This is a temporary dialog, no need to localize.
1391                    AlertDialog d = new BaseErrorDialog(mContext);
1392                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1393                    d.setCancelable(false);
1394                    d.setTitle(title);
1395                    d.setMessage(text);
1396                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1397                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1398                    mUidAlert = d;
1399                    d.show();
1400                }
1401            } break;
1402            case IM_FEELING_LUCKY_MSG: {
1403                if (mUidAlert != null) {
1404                    mUidAlert.dismiss();
1405                    mUidAlert = null;
1406                }
1407            } break;
1408            case PROC_START_TIMEOUT_MSG: {
1409                if (mDidDexOpt) {
1410                    mDidDexOpt = false;
1411                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1412                    nmsg.obj = msg.obj;
1413                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1414                    return;
1415                }
1416                ProcessRecord app = (ProcessRecord)msg.obj;
1417                synchronized (ActivityManagerService.this) {
1418                    processStartTimedOutLocked(app);
1419                }
1420            } break;
1421            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1422                synchronized (ActivityManagerService.this) {
1423                    doPendingActivityLaunchesLocked(true);
1424                }
1425            } break;
1426            case KILL_APPLICATION_MSG: {
1427                synchronized (ActivityManagerService.this) {
1428                    int appid = msg.arg1;
1429                    boolean restart = (msg.arg2 == 1);
1430                    Bundle bundle = (Bundle)msg.obj;
1431                    String pkg = bundle.getString("pkg");
1432                    String reason = bundle.getString("reason");
1433                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1434                            false, UserHandle.USER_ALL, reason);
1435                }
1436            } break;
1437            case FINALIZE_PENDING_INTENT_MSG: {
1438                ((PendingIntentRecord)msg.obj).completeFinalize();
1439            } break;
1440            case POST_HEAVY_NOTIFICATION_MSG: {
1441                INotificationManager inm = NotificationManager.getService();
1442                if (inm == null) {
1443                    return;
1444                }
1445
1446                ActivityRecord root = (ActivityRecord)msg.obj;
1447                ProcessRecord process = root.app;
1448                if (process == null) {
1449                    return;
1450                }
1451
1452                try {
1453                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1454                    String text = mContext.getString(R.string.heavy_weight_notification,
1455                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1456                    Notification notification = new Notification();
1457                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1458                    notification.when = 0;
1459                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1460                    notification.tickerText = text;
1461                    notification.defaults = 0; // please be quiet
1462                    notification.sound = null;
1463                    notification.vibrate = null;
1464                    notification.setLatestEventInfo(context, text,
1465                            mContext.getText(R.string.heavy_weight_notification_detail),
1466                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1467                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1468                                    new UserHandle(root.userId)));
1469
1470                    try {
1471                        int[] outId = new int[1];
1472                        inm.enqueueNotificationWithTag("android", "android", null,
1473                                R.string.heavy_weight_notification,
1474                                notification, outId, root.userId);
1475                    } catch (RuntimeException e) {
1476                        Slog.w(ActivityManagerService.TAG,
1477                                "Error showing notification for heavy-weight app", e);
1478                    } catch (RemoteException e) {
1479                    }
1480                } catch (NameNotFoundException e) {
1481                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1482                }
1483            } break;
1484            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1485                INotificationManager inm = NotificationManager.getService();
1486                if (inm == null) {
1487                    return;
1488                }
1489                try {
1490                    inm.cancelNotificationWithTag("android", null,
1491                            R.string.heavy_weight_notification,  msg.arg1);
1492                } catch (RuntimeException e) {
1493                    Slog.w(ActivityManagerService.TAG,
1494                            "Error canceling notification for service", e);
1495                } catch (RemoteException e) {
1496                }
1497            } break;
1498            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1499                synchronized (ActivityManagerService.this) {
1500                    checkExcessivePowerUsageLocked(true);
1501                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1502                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1503                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1504                }
1505            } break;
1506            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1507                synchronized (ActivityManagerService.this) {
1508                    ActivityRecord ar = (ActivityRecord)msg.obj;
1509                    if (mCompatModeDialog != null) {
1510                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1511                                ar.info.applicationInfo.packageName)) {
1512                            return;
1513                        }
1514                        mCompatModeDialog.dismiss();
1515                        mCompatModeDialog = null;
1516                    }
1517                    if (ar != null && false) {
1518                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1519                                ar.packageName)) {
1520                            int mode = mCompatModePackages.computeCompatModeLocked(
1521                                    ar.info.applicationInfo);
1522                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1523                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1524                                mCompatModeDialog = new CompatModeDialog(
1525                                        ActivityManagerService.this, mContext,
1526                                        ar.info.applicationInfo);
1527                                mCompatModeDialog.show();
1528                            }
1529                        }
1530                    }
1531                }
1532                break;
1533            }
1534            case DISPATCH_PROCESSES_CHANGED: {
1535                dispatchProcessesChanged();
1536                break;
1537            }
1538            case DISPATCH_PROCESS_DIED: {
1539                final int pid = msg.arg1;
1540                final int uid = msg.arg2;
1541                dispatchProcessDied(pid, uid);
1542                break;
1543            }
1544            case REPORT_MEM_USAGE_MSG: {
1545                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1546                Thread thread = new Thread() {
1547                    @Override public void run() {
1548                        final SparseArray<ProcessMemInfo> infoMap
1549                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1550                        for (int i=0, N=memInfos.size(); i<N; i++) {
1551                            ProcessMemInfo mi = memInfos.get(i);
1552                            infoMap.put(mi.pid, mi);
1553                        }
1554                        updateCpuStatsNow();
1555                        synchronized (mProcessCpuThread) {
1556                            final int N = mProcessCpuTracker.countStats();
1557                            for (int i=0; i<N; i++) {
1558                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1559                                if (st.vsize > 0) {
1560                                    long pss = Debug.getPss(st.pid, null);
1561                                    if (pss > 0) {
1562                                        if (infoMap.indexOfKey(st.pid) < 0) {
1563                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1564                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1565                                            mi.pss = pss;
1566                                            memInfos.add(mi);
1567                                        }
1568                                    }
1569                                }
1570                            }
1571                        }
1572
1573                        long totalPss = 0;
1574                        for (int i=0, N=memInfos.size(); i<N; i++) {
1575                            ProcessMemInfo mi = memInfos.get(i);
1576                            if (mi.pss == 0) {
1577                                mi.pss = Debug.getPss(mi.pid, null);
1578                            }
1579                            totalPss += mi.pss;
1580                        }
1581                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1582                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1583                                if (lhs.oomAdj != rhs.oomAdj) {
1584                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1585                                }
1586                                if (lhs.pss != rhs.pss) {
1587                                    return lhs.pss < rhs.pss ? 1 : -1;
1588                                }
1589                                return 0;
1590                            }
1591                        });
1592
1593                        StringBuilder tag = new StringBuilder(128);
1594                        StringBuilder stack = new StringBuilder(128);
1595                        tag.append("Low on memory -- ");
1596                        appendMemBucket(tag, totalPss, "total", false);
1597                        appendMemBucket(stack, totalPss, "total", true);
1598
1599                        StringBuilder logBuilder = new StringBuilder(1024);
1600                        logBuilder.append("Low on memory:\n");
1601
1602                        boolean firstLine = true;
1603                        int lastOomAdj = Integer.MIN_VALUE;
1604                        for (int i=0, N=memInfos.size(); i<N; i++) {
1605                            ProcessMemInfo mi = memInfos.get(i);
1606
1607                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1608                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1609                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1610                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1611                                if (lastOomAdj != mi.oomAdj) {
1612                                    lastOomAdj = mi.oomAdj;
1613                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1614                                        tag.append(" / ");
1615                                    }
1616                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1617                                        if (firstLine) {
1618                                            stack.append(":");
1619                                            firstLine = false;
1620                                        }
1621                                        stack.append("\n\t at ");
1622                                    } else {
1623                                        stack.append("$");
1624                                    }
1625                                } else {
1626                                    tag.append(" ");
1627                                    stack.append("$");
1628                                }
1629                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1630                                    appendMemBucket(tag, mi.pss, mi.name, false);
1631                                }
1632                                appendMemBucket(stack, mi.pss, mi.name, true);
1633                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1634                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1635                                    stack.append("(");
1636                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1637                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1638                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1639                                            stack.append(":");
1640                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1641                                        }
1642                                    }
1643                                    stack.append(")");
1644                                }
1645                            }
1646
1647                            logBuilder.append("  ");
1648                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1649                            logBuilder.append(' ');
1650                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1651                            logBuilder.append(' ');
1652                            ProcessList.appendRamKb(logBuilder, mi.pss);
1653                            logBuilder.append(" kB: ");
1654                            logBuilder.append(mi.name);
1655                            logBuilder.append(" (");
1656                            logBuilder.append(mi.pid);
1657                            logBuilder.append(") ");
1658                            logBuilder.append(mi.adjType);
1659                            logBuilder.append('\n');
1660                            if (mi.adjReason != null) {
1661                                logBuilder.append("                      ");
1662                                logBuilder.append(mi.adjReason);
1663                                logBuilder.append('\n');
1664                            }
1665                        }
1666
1667                        logBuilder.append("           ");
1668                        ProcessList.appendRamKb(logBuilder, totalPss);
1669                        logBuilder.append(" kB: TOTAL\n");
1670
1671                        long[] infos = new long[Debug.MEMINFO_COUNT];
1672                        Debug.getMemInfo(infos);
1673                        logBuilder.append("  MemInfo: ");
1674                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1675                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1676                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1677                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1678                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1679                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1680                            logBuilder.append("  ZRAM: ");
1681                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1682                            logBuilder.append(" kB RAM, ");
1683                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1684                            logBuilder.append(" kB swap total, ");
1685                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1686                            logBuilder.append(" kB swap free\n");
1687                        }
1688                        Slog.i(TAG, logBuilder.toString());
1689
1690                        StringBuilder dropBuilder = new StringBuilder(1024);
1691                        /*
1692                        StringWriter oomSw = new StringWriter();
1693                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1694                        StringWriter catSw = new StringWriter();
1695                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1696                        String[] emptyArgs = new String[] { };
1697                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1698                        oomPw.flush();
1699                        String oomString = oomSw.toString();
1700                        */
1701                        dropBuilder.append(stack);
1702                        dropBuilder.append('\n');
1703                        dropBuilder.append('\n');
1704                        dropBuilder.append(logBuilder);
1705                        dropBuilder.append('\n');
1706                        /*
1707                        dropBuilder.append(oomString);
1708                        dropBuilder.append('\n');
1709                        */
1710                        StringWriter catSw = new StringWriter();
1711                        synchronized (ActivityManagerService.this) {
1712                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1713                            String[] emptyArgs = new String[] { };
1714                            catPw.println();
1715                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1716                            catPw.println();
1717                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1718                                    false, false, null);
1719                            catPw.println();
1720                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1721                            catPw.flush();
1722                        }
1723                        dropBuilder.append(catSw.toString());
1724                        addErrorToDropBox("lowmem", null, "system_server", null,
1725                                null, tag.toString(), dropBuilder.toString(), null, null);
1726                        //Slog.i(TAG, "Sent to dropbox:");
1727                        //Slog.i(TAG, dropBuilder.toString());
1728                        synchronized (ActivityManagerService.this) {
1729                            long now = SystemClock.uptimeMillis();
1730                            if (mLastMemUsageReportTime < now) {
1731                                mLastMemUsageReportTime = now;
1732                            }
1733                        }
1734                    }
1735                };
1736                thread.start();
1737                break;
1738            }
1739            case REPORT_USER_SWITCH_MSG: {
1740                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1741                break;
1742            }
1743            case CONTINUE_USER_SWITCH_MSG: {
1744                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1745                break;
1746            }
1747            case USER_SWITCH_TIMEOUT_MSG: {
1748                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1749                break;
1750            }
1751            case IMMERSIVE_MODE_LOCK_MSG: {
1752                final boolean nextState = (msg.arg1 != 0);
1753                if (mUpdateLock.isHeld() != nextState) {
1754                    if (DEBUG_IMMERSIVE) {
1755                        final ActivityRecord r = (ActivityRecord) msg.obj;
1756                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1757                    }
1758                    if (nextState) {
1759                        mUpdateLock.acquire();
1760                    } else {
1761                        mUpdateLock.release();
1762                    }
1763                }
1764                break;
1765            }
1766            case PERSIST_URI_GRANTS_MSG: {
1767                writeGrantedUriPermissions();
1768                break;
1769            }
1770            case REQUEST_ALL_PSS_MSG: {
1771                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1772                break;
1773            }
1774            case START_PROFILES_MSG: {
1775                synchronized (ActivityManagerService.this) {
1776                    startProfilesLocked();
1777                }
1778                break;
1779            }
1780            case UPDATE_TIME: {
1781                synchronized (ActivityManagerService.this) {
1782                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1783                        ProcessRecord r = mLruProcesses.get(i);
1784                        if (r.thread != null) {
1785                            try {
1786                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1787                            } catch (RemoteException ex) {
1788                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1789                            }
1790                        }
1791                    }
1792                }
1793                break;
1794            }
1795            case SYSTEM_USER_START_MSG: {
1796                mSystemServiceManager.startUser(msg.arg1);
1797                break;
1798            }
1799            case SYSTEM_USER_CURRENT_MSG: {
1800                mSystemServiceManager.switchUser(msg.arg1);
1801                break;
1802            }
1803            }
1804        }
1805    };
1806
1807    static final int COLLECT_PSS_BG_MSG = 1;
1808
1809    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1810        @Override
1811        public void handleMessage(Message msg) {
1812            switch (msg.what) {
1813            case COLLECT_PSS_BG_MSG: {
1814                long start = SystemClock.uptimeMillis();
1815                MemInfoReader memInfo = null;
1816                synchronized (ActivityManagerService.this) {
1817                    if (mFullPssPending) {
1818                        mFullPssPending = false;
1819                        memInfo = new MemInfoReader();
1820                    }
1821                }
1822                if (memInfo != null) {
1823                    updateCpuStatsNow();
1824                    long nativeTotalPss = 0;
1825                    synchronized (mProcessCpuThread) {
1826                        final int N = mProcessCpuTracker.countStats();
1827                        for (int j=0; j<N; j++) {
1828                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1829                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1830                                // This is definitely an application process; skip it.
1831                                continue;
1832                            }
1833                            synchronized (mPidsSelfLocked) {
1834                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1835                                    // This is one of our own processes; skip it.
1836                                    continue;
1837                                }
1838                            }
1839                            nativeTotalPss += Debug.getPss(st.pid, null);
1840                        }
1841                    }
1842                    memInfo.readMemInfo();
1843                    synchronized (this) {
1844                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1845                                + (SystemClock.uptimeMillis()-start) + "ms");
1846                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1847                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1848                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1849                                        +memInfo.getSlabSizeKb(),
1850                                nativeTotalPss);
1851                    }
1852                }
1853
1854                int i=0, num=0;
1855                long[] tmp = new long[1];
1856                do {
1857                    ProcessRecord proc;
1858                    int procState;
1859                    int pid;
1860                    synchronized (ActivityManagerService.this) {
1861                        if (i >= mPendingPssProcesses.size()) {
1862                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1863                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1864                            mPendingPssProcesses.clear();
1865                            return;
1866                        }
1867                        proc = mPendingPssProcesses.get(i);
1868                        procState = proc.pssProcState;
1869                        if (proc.thread != null && procState == proc.setProcState) {
1870                            pid = proc.pid;
1871                        } else {
1872                            proc = null;
1873                            pid = 0;
1874                        }
1875                        i++;
1876                    }
1877                    if (proc != null) {
1878                        long pss = Debug.getPss(pid, tmp);
1879                        synchronized (ActivityManagerService.this) {
1880                            if (proc.thread != null && proc.setProcState == procState
1881                                    && proc.pid == pid) {
1882                                num++;
1883                                proc.lastPssTime = SystemClock.uptimeMillis();
1884                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1885                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1886                                        + ": " + pss + " lastPss=" + proc.lastPss
1887                                        + " state=" + ProcessList.makeProcStateString(procState));
1888                                if (proc.initialIdlePss == 0) {
1889                                    proc.initialIdlePss = pss;
1890                                }
1891                                proc.lastPss = pss;
1892                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1893                                    proc.lastCachedPss = pss;
1894                                }
1895                            }
1896                        }
1897                    }
1898                } while (true);
1899            }
1900            }
1901        }
1902    };
1903
1904    /**
1905     * Monitor for package changes and update our internal state.
1906     */
1907    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1908        @Override
1909        public void onPackageRemoved(String packageName, int uid) {
1910            // Remove all tasks with activities in the specified package from the list of recent tasks
1911            synchronized (ActivityManagerService.this) {
1912                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1913                    TaskRecord tr = mRecentTasks.get(i);
1914                    ComponentName cn = tr.intent.getComponent();
1915                    if (cn != null && cn.getPackageName().equals(packageName)) {
1916                        // If the package name matches, remove the task and kill the process
1917                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1918                    }
1919                }
1920            }
1921        }
1922
1923        @Override
1924        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1925            onPackageModified(packageName);
1926            return true;
1927        }
1928
1929        @Override
1930        public void onPackageModified(String packageName) {
1931            final PackageManager pm = mContext.getPackageManager();
1932            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1933                    new ArrayList<Pair<Intent, Integer>>();
1934            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1935            // Copy the list of recent tasks so that we don't hold onto the lock on
1936            // ActivityManagerService for long periods while checking if components exist.
1937            synchronized (ActivityManagerService.this) {
1938                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1939                    TaskRecord tr = mRecentTasks.get(i);
1940                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1941                }
1942            }
1943            // Check the recent tasks and filter out all tasks with components that no longer exist.
1944            Intent tmpI = new Intent();
1945            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1946                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1947                ComponentName cn = p.first.getComponent();
1948                if (cn != null && cn.getPackageName().equals(packageName)) {
1949                    try {
1950                        // Add the task to the list to remove if the component no longer exists
1951                        tmpI.setComponent(cn);
1952                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1953                            tasksToRemove.add(p.second);
1954                        }
1955                    } catch (Exception e) {}
1956                }
1957            }
1958            // Prune all the tasks with removed components from the list of recent tasks
1959            synchronized (ActivityManagerService.this) {
1960                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1961                    // Remove the task but don't kill the process (since other components in that
1962                    // package may still be running and in the background)
1963                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1964                }
1965            }
1966        }
1967
1968        @Override
1969        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1970            // Force stop the specified packages
1971            if (packages != null) {
1972                for (String pkg : packages) {
1973                    synchronized (ActivityManagerService.this) {
1974                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
1975                                "finished booting")) {
1976                            return true;
1977                        }
1978                    }
1979                }
1980            }
1981            return false;
1982        }
1983    };
1984
1985    public void setSystemProcess() {
1986        try {
1987            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1988            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1989            ServiceManager.addService("meminfo", new MemBinder(this));
1990            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1991            ServiceManager.addService("dbinfo", new DbBinder(this));
1992            if (MONITOR_CPU_USAGE) {
1993                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1994            }
1995            ServiceManager.addService("permission", new PermissionController(this));
1996
1997            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1998                    "android", STOCK_PM_FLAGS);
1999            mSystemThread.installSystemApplicationInfo(info);
2000
2001            synchronized (this) {
2002                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
2003                app.persistent = true;
2004                app.pid = MY_PID;
2005                app.maxAdj = ProcessList.SYSTEM_ADJ;
2006                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2007                mProcessNames.put(app.processName, app.uid, app);
2008                synchronized (mPidsSelfLocked) {
2009                    mPidsSelfLocked.put(app.pid, app);
2010                }
2011                updateLruProcessLocked(app, false, null);
2012                updateOomAdjLocked();
2013            }
2014        } catch (PackageManager.NameNotFoundException e) {
2015            throw new RuntimeException(
2016                    "Unable to find android system package", e);
2017        }
2018    }
2019
2020    public void setWindowManager(WindowManagerService wm) {
2021        mWindowManager = wm;
2022        mStackSupervisor.setWindowManager(wm);
2023    }
2024
2025    public void startObservingNativeCrashes() {
2026        final NativeCrashListener ncl = new NativeCrashListener(this);
2027        ncl.start();
2028    }
2029
2030    public IAppOpsService getAppOpsService() {
2031        return mAppOpsService;
2032    }
2033
2034    static class MemBinder extends Binder {
2035        ActivityManagerService mActivityManagerService;
2036        MemBinder(ActivityManagerService activityManagerService) {
2037            mActivityManagerService = activityManagerService;
2038        }
2039
2040        @Override
2041        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2042            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2043                    != PackageManager.PERMISSION_GRANTED) {
2044                pw.println("Permission Denial: can't dump meminfo from from pid="
2045                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2046                        + " without permission " + android.Manifest.permission.DUMP);
2047                return;
2048            }
2049
2050            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2051        }
2052    }
2053
2054    static class GraphicsBinder extends Binder {
2055        ActivityManagerService mActivityManagerService;
2056        GraphicsBinder(ActivityManagerService activityManagerService) {
2057            mActivityManagerService = activityManagerService;
2058        }
2059
2060        @Override
2061        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2062            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2063                    != PackageManager.PERMISSION_GRANTED) {
2064                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2065                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2066                        + " without permission " + android.Manifest.permission.DUMP);
2067                return;
2068            }
2069
2070            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2071        }
2072    }
2073
2074    static class DbBinder extends Binder {
2075        ActivityManagerService mActivityManagerService;
2076        DbBinder(ActivityManagerService activityManagerService) {
2077            mActivityManagerService = activityManagerService;
2078        }
2079
2080        @Override
2081        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2082            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2083                    != PackageManager.PERMISSION_GRANTED) {
2084                pw.println("Permission Denial: can't dump dbinfo from from pid="
2085                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2086                        + " without permission " + android.Manifest.permission.DUMP);
2087                return;
2088            }
2089
2090            mActivityManagerService.dumpDbInfo(fd, pw, args);
2091        }
2092    }
2093
2094    static class CpuBinder extends Binder {
2095        ActivityManagerService mActivityManagerService;
2096        CpuBinder(ActivityManagerService activityManagerService) {
2097            mActivityManagerService = activityManagerService;
2098        }
2099
2100        @Override
2101        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2102            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2103                    != PackageManager.PERMISSION_GRANTED) {
2104                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2105                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2106                        + " without permission " + android.Manifest.permission.DUMP);
2107                return;
2108            }
2109
2110            synchronized (mActivityManagerService.mProcessCpuThread) {
2111                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2112                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2113                        SystemClock.uptimeMillis()));
2114            }
2115        }
2116    }
2117
2118    public static final class Lifecycle extends SystemService {
2119        private final ActivityManagerService mService;
2120
2121        public Lifecycle(Context context) {
2122            super(context);
2123            mService = new ActivityManagerService(context);
2124        }
2125
2126        @Override
2127        public void onStart() {
2128            mService.start();
2129        }
2130
2131        public ActivityManagerService getService() {
2132            return mService;
2133        }
2134    }
2135
2136    // Note: This method is invoked on the main thread but may need to attach various
2137    // handlers to other threads.  So take care to be explicit about the looper.
2138    public ActivityManagerService(Context systemContext) {
2139        mContext = systemContext;
2140        mFactoryTest = FactoryTest.getMode();
2141        mSystemThread = ActivityThread.currentActivityThread();
2142
2143        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2144
2145        mHandlerThread = new ServiceThread(TAG,
2146                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2147        mHandlerThread.start();
2148        mHandler = new MainHandler(mHandlerThread.getLooper());
2149
2150        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2151                "foreground", BROADCAST_FG_TIMEOUT, false);
2152        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2153                "background", BROADCAST_BG_TIMEOUT, true);
2154        mBroadcastQueues[0] = mFgBroadcastQueue;
2155        mBroadcastQueues[1] = mBgBroadcastQueue;
2156
2157        mServices = new ActiveServices(this);
2158        mProviderMap = new ProviderMap(this);
2159
2160        // TODO: Move creation of battery stats service outside of activity manager service.
2161        File dataDir = Environment.getDataDirectory();
2162        File systemDir = new File(dataDir, "system");
2163        systemDir.mkdirs();
2164        mBatteryStatsService = new BatteryStatsService(new File(
2165                systemDir, "batterystats.bin").toString(), mHandler);
2166        mBatteryStatsService.getActiveStatistics().readLocked();
2167        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2168        mOnBattery = DEBUG_POWER ? true
2169                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2170        mBatteryStatsService.getActiveStatistics().setCallback(this);
2171
2172        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2173
2174        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
2175        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2176
2177        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2178
2179        // User 0 is the first and only user that runs at boot.
2180        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2181        mUserLru.add(Integer.valueOf(0));
2182        updateStartedUserArrayLocked();
2183
2184        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2185            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2186
2187        mConfiguration.setToDefaults();
2188        mConfiguration.setLocale(Locale.getDefault());
2189
2190        mConfigurationSeq = mConfiguration.seq = 1;
2191        mProcessCpuTracker.init();
2192
2193        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2194        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2195        mStackSupervisor = new ActivityStackSupervisor(this);
2196        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2197
2198        mProcessCpuThread = new Thread("CpuTracker") {
2199            @Override
2200            public void run() {
2201                while (true) {
2202                    try {
2203                        try {
2204                            synchronized(this) {
2205                                final long now = SystemClock.uptimeMillis();
2206                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2207                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2208                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2209                                //        + ", write delay=" + nextWriteDelay);
2210                                if (nextWriteDelay < nextCpuDelay) {
2211                                    nextCpuDelay = nextWriteDelay;
2212                                }
2213                                if (nextCpuDelay > 0) {
2214                                    mProcessCpuMutexFree.set(true);
2215                                    this.wait(nextCpuDelay);
2216                                }
2217                            }
2218                        } catch (InterruptedException e) {
2219                        }
2220                        updateCpuStatsNow();
2221                    } catch (Exception e) {
2222                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2223                    }
2224                }
2225            }
2226        };
2227
2228        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2229
2230        Watchdog.getInstance().addMonitor(this);
2231        Watchdog.getInstance().addThread(mHandler);
2232    }
2233
2234    public void setSystemServiceManager(SystemServiceManager mgr) {
2235        mSystemServiceManager = mgr;
2236    }
2237
2238    private void start() {
2239        mProcessCpuThread.start();
2240
2241        mBatteryStatsService.publish(mContext);
2242        mUsageStatsService.publish(mContext);
2243        mAppOpsService.publish(mContext);
2244        Slog.d("AppOps", "AppOpsService published");
2245        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2246    }
2247
2248    public void initPowerManagement() {
2249        mStackSupervisor.initPowerManagement();
2250        mBatteryStatsService.initPowerManagement();
2251    }
2252
2253    @Override
2254    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2255            throws RemoteException {
2256        if (code == SYSPROPS_TRANSACTION) {
2257            // We need to tell all apps about the system property change.
2258            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2259            synchronized(this) {
2260                final int NP = mProcessNames.getMap().size();
2261                for (int ip=0; ip<NP; ip++) {
2262                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2263                    final int NA = apps.size();
2264                    for (int ia=0; ia<NA; ia++) {
2265                        ProcessRecord app = apps.valueAt(ia);
2266                        if (app.thread != null) {
2267                            procs.add(app.thread.asBinder());
2268                        }
2269                    }
2270                }
2271            }
2272
2273            int N = procs.size();
2274            for (int i=0; i<N; i++) {
2275                Parcel data2 = Parcel.obtain();
2276                try {
2277                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2278                } catch (RemoteException e) {
2279                }
2280                data2.recycle();
2281            }
2282        }
2283        try {
2284            return super.onTransact(code, data, reply, flags);
2285        } catch (RuntimeException e) {
2286            // The activity manager only throws security exceptions, so let's
2287            // log all others.
2288            if (!(e instanceof SecurityException)) {
2289                Slog.wtf(TAG, "Activity Manager Crash", e);
2290            }
2291            throw e;
2292        }
2293    }
2294
2295    void updateCpuStats() {
2296        final long now = SystemClock.uptimeMillis();
2297        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2298            return;
2299        }
2300        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2301            synchronized (mProcessCpuThread) {
2302                mProcessCpuThread.notify();
2303            }
2304        }
2305    }
2306
2307    void updateCpuStatsNow() {
2308        synchronized (mProcessCpuThread) {
2309            mProcessCpuMutexFree.set(false);
2310            final long now = SystemClock.uptimeMillis();
2311            boolean haveNewCpuStats = false;
2312
2313            if (MONITOR_CPU_USAGE &&
2314                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2315                mLastCpuTime.set(now);
2316                haveNewCpuStats = true;
2317                mProcessCpuTracker.update();
2318                //Slog.i(TAG, mProcessCpu.printCurrentState());
2319                //Slog.i(TAG, "Total CPU usage: "
2320                //        + mProcessCpu.getTotalCpuPercent() + "%");
2321
2322                // Slog the cpu usage if the property is set.
2323                if ("true".equals(SystemProperties.get("events.cpu"))) {
2324                    int user = mProcessCpuTracker.getLastUserTime();
2325                    int system = mProcessCpuTracker.getLastSystemTime();
2326                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2327                    int irq = mProcessCpuTracker.getLastIrqTime();
2328                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2329                    int idle = mProcessCpuTracker.getLastIdleTime();
2330
2331                    int total = user + system + iowait + irq + softIrq + idle;
2332                    if (total == 0) total = 1;
2333
2334                    EventLog.writeEvent(EventLogTags.CPU,
2335                            ((user+system+iowait+irq+softIrq) * 100) / total,
2336                            (user * 100) / total,
2337                            (system * 100) / total,
2338                            (iowait * 100) / total,
2339                            (irq * 100) / total,
2340                            (softIrq * 100) / total);
2341                }
2342            }
2343
2344            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2345            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2346            synchronized(bstats) {
2347                synchronized(mPidsSelfLocked) {
2348                    if (haveNewCpuStats) {
2349                        if (mOnBattery) {
2350                            int perc = bstats.startAddingCpuLocked();
2351                            int totalUTime = 0;
2352                            int totalSTime = 0;
2353                            final int N = mProcessCpuTracker.countStats();
2354                            for (int i=0; i<N; i++) {
2355                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2356                                if (!st.working) {
2357                                    continue;
2358                                }
2359                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2360                                int otherUTime = (st.rel_utime*perc)/100;
2361                                int otherSTime = (st.rel_stime*perc)/100;
2362                                totalUTime += otherUTime;
2363                                totalSTime += otherSTime;
2364                                if (pr != null) {
2365                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2366                                    if (ps == null || !ps.isActive()) {
2367                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2368                                                pr.info.uid, pr.processName);
2369                                    }
2370                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2371                                            st.rel_stime-otherSTime);
2372                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2373                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2374                                } else {
2375                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2376                                    if (ps == null || !ps.isActive()) {
2377                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2378                                                bstats.mapUid(st.uid), st.name);
2379                                    }
2380                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2381                                            st.rel_stime-otherSTime);
2382                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2383                                }
2384                            }
2385                            bstats.finishAddingCpuLocked(perc, totalUTime,
2386                                    totalSTime, cpuSpeedTimes);
2387                        }
2388                    }
2389                }
2390
2391                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2392                    mLastWriteTime = now;
2393                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2394                }
2395            }
2396        }
2397    }
2398
2399    @Override
2400    public void batteryNeedsCpuUpdate() {
2401        updateCpuStatsNow();
2402    }
2403
2404    @Override
2405    public void batteryPowerChanged(boolean onBattery) {
2406        // When plugging in, update the CPU stats first before changing
2407        // the plug state.
2408        updateCpuStatsNow();
2409        synchronized (this) {
2410            synchronized(mPidsSelfLocked) {
2411                mOnBattery = DEBUG_POWER ? true : onBattery;
2412            }
2413        }
2414    }
2415
2416    /**
2417     * Initialize the application bind args. These are passed to each
2418     * process when the bindApplication() IPC is sent to the process. They're
2419     * lazily setup to make sure the services are running when they're asked for.
2420     */
2421    private HashMap<String, IBinder> getCommonServicesLocked() {
2422        if (mAppBindArgs == null) {
2423            mAppBindArgs = new HashMap<String, IBinder>();
2424
2425            // Setup the application init args
2426            mAppBindArgs.put("package", ServiceManager.getService("package"));
2427            mAppBindArgs.put("window", ServiceManager.getService("window"));
2428            mAppBindArgs.put(Context.ALARM_SERVICE,
2429                    ServiceManager.getService(Context.ALARM_SERVICE));
2430        }
2431        return mAppBindArgs;
2432    }
2433
2434    final void setFocusedActivityLocked(ActivityRecord r) {
2435        if (mFocusedActivity != r) {
2436            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2437            mFocusedActivity = r;
2438            if (r.task != null && r.task.voiceInteractor != null) {
2439                startRunningVoiceLocked();
2440            } else {
2441                finishRunningVoiceLocked();
2442            }
2443            mStackSupervisor.setFocusedStack(r);
2444            if (r != null) {
2445                mWindowManager.setFocusedApp(r.appToken, true);
2446            }
2447            applyUpdateLockStateLocked(r);
2448        }
2449    }
2450
2451    final void clearFocusedActivity(ActivityRecord r) {
2452        if (mFocusedActivity == r) {
2453            mFocusedActivity = null;
2454        }
2455    }
2456
2457    @Override
2458    public void setFocusedStack(int stackId) {
2459        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2460        synchronized (ActivityManagerService.this) {
2461            ActivityStack stack = mStackSupervisor.getStack(stackId);
2462            if (stack != null) {
2463                ActivityRecord r = stack.topRunningActivityLocked(null);
2464                if (r != null) {
2465                    setFocusedActivityLocked(r);
2466                }
2467            }
2468        }
2469    }
2470
2471    @Override
2472    public void notifyActivityDrawn(IBinder token) {
2473        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2474        synchronized (this) {
2475            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2476            if (r != null) {
2477                r.task.stack.notifyActivityDrawnLocked(r);
2478            }
2479        }
2480    }
2481
2482    final void applyUpdateLockStateLocked(ActivityRecord r) {
2483        // Modifications to the UpdateLock state are done on our handler, outside
2484        // the activity manager's locks.  The new state is determined based on the
2485        // state *now* of the relevant activity record.  The object is passed to
2486        // the handler solely for logging detail, not to be consulted/modified.
2487        final boolean nextState = r != null && r.immersive;
2488        mHandler.sendMessage(
2489                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2490    }
2491
2492    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2493        Message msg = Message.obtain();
2494        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2495        msg.obj = r.task.askedCompatMode ? null : r;
2496        mHandler.sendMessage(msg);
2497    }
2498
2499    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2500            String what, Object obj, ProcessRecord srcApp) {
2501        app.lastActivityTime = now;
2502
2503        if (app.activities.size() > 0) {
2504            // Don't want to touch dependent processes that are hosting activities.
2505            return index;
2506        }
2507
2508        int lrui = mLruProcesses.lastIndexOf(app);
2509        if (lrui < 0) {
2510            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2511                    + what + " " + obj + " from " + srcApp);
2512            return index;
2513        }
2514
2515        if (lrui >= index) {
2516            // Don't want to cause this to move dependent processes *back* in the
2517            // list as if they were less frequently used.
2518            return index;
2519        }
2520
2521        if (lrui >= mLruProcessActivityStart) {
2522            // Don't want to touch dependent processes that are hosting activities.
2523            return index;
2524        }
2525
2526        mLruProcesses.remove(lrui);
2527        if (index > 0) {
2528            index--;
2529        }
2530        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2531                + " in LRU list: " + app);
2532        mLruProcesses.add(index, app);
2533        return index;
2534    }
2535
2536    final void removeLruProcessLocked(ProcessRecord app) {
2537        int lrui = mLruProcesses.lastIndexOf(app);
2538        if (lrui >= 0) {
2539            if (lrui <= mLruProcessActivityStart) {
2540                mLruProcessActivityStart--;
2541            }
2542            if (lrui <= mLruProcessServiceStart) {
2543                mLruProcessServiceStart--;
2544            }
2545            mLruProcesses.remove(lrui);
2546        }
2547    }
2548
2549    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2550            ProcessRecord client) {
2551        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2552                || app.treatLikeActivity;
2553        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2554        if (!activityChange && hasActivity) {
2555            // The process has activities, so we are only allowing activity-based adjustments
2556            // to move it.  It should be kept in the front of the list with other
2557            // processes that have activities, and we don't want those to change their
2558            // order except due to activity operations.
2559            return;
2560        }
2561
2562        mLruSeq++;
2563        final long now = SystemClock.uptimeMillis();
2564        app.lastActivityTime = now;
2565
2566        // First a quick reject: if the app is already at the position we will
2567        // put it, then there is nothing to do.
2568        if (hasActivity) {
2569            final int N = mLruProcesses.size();
2570            if (N > 0 && mLruProcesses.get(N-1) == app) {
2571                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2572                return;
2573            }
2574        } else {
2575            if (mLruProcessServiceStart > 0
2576                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2577                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2578                return;
2579            }
2580        }
2581
2582        int lrui = mLruProcesses.lastIndexOf(app);
2583
2584        if (app.persistent && lrui >= 0) {
2585            // We don't care about the position of persistent processes, as long as
2586            // they are in the list.
2587            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2588            return;
2589        }
2590
2591        /* In progress: compute new position first, so we can avoid doing work
2592           if the process is not actually going to move.  Not yet working.
2593        int addIndex;
2594        int nextIndex;
2595        boolean inActivity = false, inService = false;
2596        if (hasActivity) {
2597            // Process has activities, put it at the very tipsy-top.
2598            addIndex = mLruProcesses.size();
2599            nextIndex = mLruProcessServiceStart;
2600            inActivity = true;
2601        } else if (hasService) {
2602            // Process has services, put it at the top of the service list.
2603            addIndex = mLruProcessActivityStart;
2604            nextIndex = mLruProcessServiceStart;
2605            inActivity = true;
2606            inService = true;
2607        } else  {
2608            // Process not otherwise of interest, it goes to the top of the non-service area.
2609            addIndex = mLruProcessServiceStart;
2610            if (client != null) {
2611                int clientIndex = mLruProcesses.lastIndexOf(client);
2612                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2613                        + app);
2614                if (clientIndex >= 0 && addIndex > clientIndex) {
2615                    addIndex = clientIndex;
2616                }
2617            }
2618            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2619        }
2620
2621        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2622                + mLruProcessActivityStart + "): " + app);
2623        */
2624
2625        if (lrui >= 0) {
2626            if (lrui < mLruProcessActivityStart) {
2627                mLruProcessActivityStart--;
2628            }
2629            if (lrui < mLruProcessServiceStart) {
2630                mLruProcessServiceStart--;
2631            }
2632            /*
2633            if (addIndex > lrui) {
2634                addIndex--;
2635            }
2636            if (nextIndex > lrui) {
2637                nextIndex--;
2638            }
2639            */
2640            mLruProcesses.remove(lrui);
2641        }
2642
2643        /*
2644        mLruProcesses.add(addIndex, app);
2645        if (inActivity) {
2646            mLruProcessActivityStart++;
2647        }
2648        if (inService) {
2649            mLruProcessActivityStart++;
2650        }
2651        */
2652
2653        int nextIndex;
2654        if (hasActivity) {
2655            final int N = mLruProcesses.size();
2656            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2657                // Process doesn't have activities, but has clients with
2658                // activities...  move it up, but one below the top (the top
2659                // should always have a real activity).
2660                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2661                mLruProcesses.add(N-1, app);
2662                // To keep it from spamming the LRU list (by making a bunch of clients),
2663                // we will push down any other entries owned by the app.
2664                final int uid = app.info.uid;
2665                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2666                    ProcessRecord subProc = mLruProcesses.get(i);
2667                    if (subProc.info.uid == uid) {
2668                        // We want to push this one down the list.  If the process after
2669                        // it is for the same uid, however, don't do so, because we don't
2670                        // want them internally to be re-ordered.
2671                        if (mLruProcesses.get(i-1).info.uid != uid) {
2672                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2673                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2674                            ProcessRecord tmp = mLruProcesses.get(i);
2675                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2676                            mLruProcesses.set(i-1, tmp);
2677                            i--;
2678                        }
2679                    } else {
2680                        // A gap, we can stop here.
2681                        break;
2682                    }
2683                }
2684            } else {
2685                // Process has activities, put it at the very tipsy-top.
2686                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2687                mLruProcesses.add(app);
2688            }
2689            nextIndex = mLruProcessServiceStart;
2690        } else if (hasService) {
2691            // Process has services, put it at the top of the service list.
2692            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2693            mLruProcesses.add(mLruProcessActivityStart, app);
2694            nextIndex = mLruProcessServiceStart;
2695            mLruProcessActivityStart++;
2696        } else  {
2697            // Process not otherwise of interest, it goes to the top of the non-service area.
2698            int index = mLruProcessServiceStart;
2699            if (client != null) {
2700                // If there is a client, don't allow the process to be moved up higher
2701                // in the list than that client.
2702                int clientIndex = mLruProcesses.lastIndexOf(client);
2703                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2704                        + " when updating " + app);
2705                if (clientIndex <= lrui) {
2706                    // Don't allow the client index restriction to push it down farther in the
2707                    // list than it already is.
2708                    clientIndex = lrui;
2709                }
2710                if (clientIndex >= 0 && index > clientIndex) {
2711                    index = clientIndex;
2712                }
2713            }
2714            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2715            mLruProcesses.add(index, app);
2716            nextIndex = index-1;
2717            mLruProcessActivityStart++;
2718            mLruProcessServiceStart++;
2719        }
2720
2721        // If the app is currently using a content provider or service,
2722        // bump those processes as well.
2723        for (int j=app.connections.size()-1; j>=0; j--) {
2724            ConnectionRecord cr = app.connections.valueAt(j);
2725            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2726                    && cr.binding.service.app != null
2727                    && cr.binding.service.app.lruSeq != mLruSeq
2728                    && !cr.binding.service.app.persistent) {
2729                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2730                        "service connection", cr, app);
2731            }
2732        }
2733        for (int j=app.conProviders.size()-1; j>=0; j--) {
2734            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2735            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2736                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2737                        "provider reference", cpr, app);
2738            }
2739        }
2740    }
2741
2742    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2743        if (uid == Process.SYSTEM_UID) {
2744            // The system gets to run in any process.  If there are multiple
2745            // processes with the same uid, just pick the first (this
2746            // should never happen).
2747            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2748            if (procs == null) return null;
2749            final int N = procs.size();
2750            for (int i = 0; i < N; i++) {
2751                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2752            }
2753        }
2754        ProcessRecord proc = mProcessNames.get(processName, uid);
2755        if (false && proc != null && !keepIfLarge
2756                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2757                && proc.lastCachedPss >= 4000) {
2758            // Turn this condition on to cause killing to happen regularly, for testing.
2759            if (proc.baseProcessTracker != null) {
2760                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2761            }
2762            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2763                    + "k from cached");
2764        } else if (proc != null && !keepIfLarge
2765                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2766                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2767            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2768            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2769                if (proc.baseProcessTracker != null) {
2770                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2771                }
2772                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2773                        + "k from cached");
2774            }
2775        }
2776        return proc;
2777    }
2778
2779    void ensurePackageDexOpt(String packageName) {
2780        IPackageManager pm = AppGlobals.getPackageManager();
2781        try {
2782            if (pm.performDexOpt(packageName)) {
2783                mDidDexOpt = true;
2784            }
2785        } catch (RemoteException e) {
2786        }
2787    }
2788
2789    boolean isNextTransitionForward() {
2790        int transit = mWindowManager.getPendingAppTransition();
2791        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2792                || transit == AppTransition.TRANSIT_TASK_OPEN
2793                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2794    }
2795
2796    final ProcessRecord startProcessLocked(String processName,
2797            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2798            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2799            boolean isolated, boolean keepIfLarge) {
2800        ProcessRecord app;
2801        if (!isolated) {
2802            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2803        } else {
2804            // If this is an isolated process, it can't re-use an existing process.
2805            app = null;
2806        }
2807        // We don't have to do anything more if:
2808        // (1) There is an existing application record; and
2809        // (2) The caller doesn't think it is dead, OR there is no thread
2810        //     object attached to it so we know it couldn't have crashed; and
2811        // (3) There is a pid assigned to it, so it is either starting or
2812        //     already running.
2813        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2814                + " app=" + app + " knownToBeDead=" + knownToBeDead
2815                + " thread=" + (app != null ? app.thread : null)
2816                + " pid=" + (app != null ? app.pid : -1));
2817        if (app != null && app.pid > 0) {
2818            if (!knownToBeDead || app.thread == null) {
2819                // We already have the app running, or are waiting for it to
2820                // come up (we have a pid but not yet its thread), so keep it.
2821                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2822                // If this is a new package in the process, add the package to the list
2823                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2824                return app;
2825            }
2826
2827            // An application record is attached to a previous process,
2828            // clean it up now.
2829            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2830            handleAppDiedLocked(app, true, true);
2831        }
2832
2833        String hostingNameStr = hostingName != null
2834                ? hostingName.flattenToShortString() : null;
2835
2836        if (!isolated) {
2837            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2838                // If we are in the background, then check to see if this process
2839                // is bad.  If so, we will just silently fail.
2840                if (mBadProcesses.get(info.processName, info.uid) != null) {
2841                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2842                            + "/" + info.processName);
2843                    return null;
2844                }
2845            } else {
2846                // When the user is explicitly starting a process, then clear its
2847                // crash count so that we won't make it bad until they see at
2848                // least one crash dialog again, and make the process good again
2849                // if it had been bad.
2850                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2851                        + "/" + info.processName);
2852                mProcessCrashTimes.remove(info.processName, info.uid);
2853                if (mBadProcesses.get(info.processName, info.uid) != null) {
2854                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2855                            UserHandle.getUserId(info.uid), info.uid,
2856                            info.processName);
2857                    mBadProcesses.remove(info.processName, info.uid);
2858                    if (app != null) {
2859                        app.bad = false;
2860                    }
2861                }
2862            }
2863        }
2864
2865        if (app == null) {
2866            app = newProcessRecordLocked(info, processName, isolated);
2867            if (app == null) {
2868                Slog.w(TAG, "Failed making new process record for "
2869                        + processName + "/" + info.uid + " isolated=" + isolated);
2870                return null;
2871            }
2872            mProcessNames.put(processName, app.uid, app);
2873            if (isolated) {
2874                mIsolatedProcesses.put(app.uid, app);
2875            }
2876        } else {
2877            // If this is a new package in the process, add the package to the list
2878            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2879        }
2880
2881        // If the system is not ready yet, then hold off on starting this
2882        // process until it is.
2883        if (!mProcessesReady
2884                && !isAllowedWhileBooting(info)
2885                && !allowWhileBooting) {
2886            if (!mProcessesOnHold.contains(app)) {
2887                mProcessesOnHold.add(app);
2888            }
2889            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2890            return app;
2891        }
2892
2893        startProcessLocked(app, hostingType, hostingNameStr, null /* ABI override */);
2894        return (app.pid != 0) ? app : null;
2895    }
2896
2897    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2898        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2899    }
2900
2901    private final void startProcessLocked(ProcessRecord app,
2902            String hostingType, String hostingNameStr, String abiOverride) {
2903        if (app.pid > 0 && app.pid != MY_PID) {
2904            synchronized (mPidsSelfLocked) {
2905                mPidsSelfLocked.remove(app.pid);
2906                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2907            }
2908            app.setPid(0);
2909        }
2910
2911        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2912                "startProcessLocked removing on hold: " + app);
2913        mProcessesOnHold.remove(app);
2914
2915        updateCpuStats();
2916
2917        try {
2918            int uid = app.uid;
2919
2920            int[] gids = null;
2921            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2922            if (!app.isolated) {
2923                int[] permGids = null;
2924                try {
2925                    final PackageManager pm = mContext.getPackageManager();
2926                    permGids = pm.getPackageGids(app.info.packageName);
2927
2928                    if (Environment.isExternalStorageEmulated()) {
2929                        if (pm.checkPermission(
2930                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2931                                app.info.packageName) == PERMISSION_GRANTED) {
2932                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2933                        } else {
2934                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2935                        }
2936                    }
2937                } catch (PackageManager.NameNotFoundException e) {
2938                    Slog.w(TAG, "Unable to retrieve gids", e);
2939                }
2940
2941                /*
2942                 * Add shared application and profile GIDs so applications can share some
2943                 * resources like shared libraries and access user-wide resources
2944                 */
2945                if (permGids == null) {
2946                    gids = new int[2];
2947                } else {
2948                    gids = new int[permGids.length + 2];
2949                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2950                }
2951                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2952                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2953            }
2954            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2955                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2956                        && mTopComponent != null
2957                        && app.processName.equals(mTopComponent.getPackageName())) {
2958                    uid = 0;
2959                }
2960                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2961                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2962                    uid = 0;
2963                }
2964            }
2965            int debugFlags = 0;
2966            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2967                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2968                // Also turn on CheckJNI for debuggable apps. It's quite
2969                // awkward to turn on otherwise.
2970                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2971            }
2972            // Run the app in safe mode if its manifest requests so or the
2973            // system is booted in safe mode.
2974            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2975                mSafeMode == true) {
2976                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2977            }
2978            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2979                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2980            }
2981            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2982                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2983            }
2984            if ("1".equals(SystemProperties.get("debug.assert"))) {
2985                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2986            }
2987
2988            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.cpuAbi;
2989            if (requiredAbi == null) {
2990                requiredAbi = Build.SUPPORTED_ABIS[0];
2991            }
2992
2993            // Start the process.  It will either succeed and return a result containing
2994            // the PID of the new process, or else throw a RuntimeException.
2995            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2996                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2997                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
2998
2999            if (app.isolated) {
3000                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3001            }
3002            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3003
3004            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3005                    UserHandle.getUserId(uid), startResult.pid, uid,
3006                    app.processName, hostingType,
3007                    hostingNameStr != null ? hostingNameStr : "");
3008
3009            if (app.persistent) {
3010                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3011            }
3012
3013            StringBuilder buf = mStringBuilder;
3014            buf.setLength(0);
3015            buf.append("Start proc ");
3016            buf.append(app.processName);
3017            buf.append(" for ");
3018            buf.append(hostingType);
3019            if (hostingNameStr != null) {
3020                buf.append(" ");
3021                buf.append(hostingNameStr);
3022            }
3023            buf.append(": pid=");
3024            buf.append(startResult.pid);
3025            buf.append(" uid=");
3026            buf.append(uid);
3027            buf.append(" gids={");
3028            if (gids != null) {
3029                for (int gi=0; gi<gids.length; gi++) {
3030                    if (gi != 0) buf.append(", ");
3031                    buf.append(gids[gi]);
3032
3033                }
3034            }
3035            buf.append("}");
3036            if (requiredAbi != null) {
3037                buf.append(" abi=");
3038                buf.append(requiredAbi);
3039            }
3040            Slog.i(TAG, buf.toString());
3041            app.setPid(startResult.pid);
3042            app.usingWrapper = startResult.usingWrapper;
3043            app.removed = false;
3044            app.killedByAm = false;
3045            synchronized (mPidsSelfLocked) {
3046                this.mPidsSelfLocked.put(startResult.pid, app);
3047                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3048                msg.obj = app;
3049                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3050                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3051            }
3052        } catch (RuntimeException e) {
3053            // XXX do better error recovery.
3054            app.setPid(0);
3055            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3056            if (app.isolated) {
3057                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3058            }
3059            Slog.e(TAG, "Failure starting process " + app.processName, e);
3060        }
3061    }
3062
3063    void updateUsageStats(ActivityRecord component, boolean resumed) {
3064        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3065        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3066        if (resumed) {
3067            mUsageStatsService.noteResumeComponent(component.realActivity);
3068            synchronized (stats) {
3069                stats.noteActivityResumedLocked(component.app.uid);
3070            }
3071        } else {
3072            mUsageStatsService.notePauseComponent(component.realActivity);
3073            synchronized (stats) {
3074                stats.noteActivityPausedLocked(component.app.uid);
3075            }
3076        }
3077    }
3078
3079    Intent getHomeIntent() {
3080        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3081        intent.setComponent(mTopComponent);
3082        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3083            intent.addCategory(Intent.CATEGORY_HOME);
3084        }
3085        return intent;
3086    }
3087
3088    boolean startHomeActivityLocked(int userId) {
3089        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3090                && mTopAction == null) {
3091            // We are running in factory test mode, but unable to find
3092            // the factory test app, so just sit around displaying the
3093            // error message and don't try to start anything.
3094            return false;
3095        }
3096        Intent intent = getHomeIntent();
3097        ActivityInfo aInfo =
3098            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3099        if (aInfo != null) {
3100            intent.setComponent(new ComponentName(
3101                    aInfo.applicationInfo.packageName, aInfo.name));
3102            // Don't do this if the home app is currently being
3103            // instrumented.
3104            aInfo = new ActivityInfo(aInfo);
3105            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3106            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3107                    aInfo.applicationInfo.uid, true);
3108            if (app == null || app.instrumentationClass == null) {
3109                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3110                mStackSupervisor.startHomeActivity(intent, aInfo);
3111            }
3112        }
3113
3114        return true;
3115    }
3116
3117    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3118        ActivityInfo ai = null;
3119        ComponentName comp = intent.getComponent();
3120        try {
3121            if (comp != null) {
3122                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3123            } else {
3124                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3125                        intent,
3126                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3127                            flags, userId);
3128
3129                if (info != null) {
3130                    ai = info.activityInfo;
3131                }
3132            }
3133        } catch (RemoteException e) {
3134            // ignore
3135        }
3136
3137        return ai;
3138    }
3139
3140    /**
3141     * Starts the "new version setup screen" if appropriate.
3142     */
3143    void startSetupActivityLocked() {
3144        // Only do this once per boot.
3145        if (mCheckedForSetup) {
3146            return;
3147        }
3148
3149        // We will show this screen if the current one is a different
3150        // version than the last one shown, and we are not running in
3151        // low-level factory test mode.
3152        final ContentResolver resolver = mContext.getContentResolver();
3153        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3154                Settings.Global.getInt(resolver,
3155                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3156            mCheckedForSetup = true;
3157
3158            // See if we should be showing the platform update setup UI.
3159            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3160            List<ResolveInfo> ris = mContext.getPackageManager()
3161                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3162
3163            // We don't allow third party apps to replace this.
3164            ResolveInfo ri = null;
3165            for (int i=0; ris != null && i<ris.size(); i++) {
3166                if ((ris.get(i).activityInfo.applicationInfo.flags
3167                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3168                    ri = ris.get(i);
3169                    break;
3170                }
3171            }
3172
3173            if (ri != null) {
3174                String vers = ri.activityInfo.metaData != null
3175                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3176                        : null;
3177                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3178                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3179                            Intent.METADATA_SETUP_VERSION);
3180                }
3181                String lastVers = Settings.Secure.getString(
3182                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3183                if (vers != null && !vers.equals(lastVers)) {
3184                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3185                    intent.setComponent(new ComponentName(
3186                            ri.activityInfo.packageName, ri.activityInfo.name));
3187                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3188                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3189                }
3190            }
3191        }
3192    }
3193
3194    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3195        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3196    }
3197
3198    void enforceNotIsolatedCaller(String caller) {
3199        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3200            throw new SecurityException("Isolated process not allowed to call " + caller);
3201        }
3202    }
3203
3204    @Override
3205    public int getFrontActivityScreenCompatMode() {
3206        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3207        synchronized (this) {
3208            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3209        }
3210    }
3211
3212    @Override
3213    public void setFrontActivityScreenCompatMode(int mode) {
3214        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3215                "setFrontActivityScreenCompatMode");
3216        synchronized (this) {
3217            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3218        }
3219    }
3220
3221    @Override
3222    public int getPackageScreenCompatMode(String packageName) {
3223        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3224        synchronized (this) {
3225            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3226        }
3227    }
3228
3229    @Override
3230    public void setPackageScreenCompatMode(String packageName, int mode) {
3231        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3232                "setPackageScreenCompatMode");
3233        synchronized (this) {
3234            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3235        }
3236    }
3237
3238    @Override
3239    public boolean getPackageAskScreenCompat(String packageName) {
3240        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3241        synchronized (this) {
3242            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3243        }
3244    }
3245
3246    @Override
3247    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3248        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3249                "setPackageAskScreenCompat");
3250        synchronized (this) {
3251            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3252        }
3253    }
3254
3255    private void dispatchProcessesChanged() {
3256        int N;
3257        synchronized (this) {
3258            N = mPendingProcessChanges.size();
3259            if (mActiveProcessChanges.length < N) {
3260                mActiveProcessChanges = new ProcessChangeItem[N];
3261            }
3262            mPendingProcessChanges.toArray(mActiveProcessChanges);
3263            mAvailProcessChanges.addAll(mPendingProcessChanges);
3264            mPendingProcessChanges.clear();
3265            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3266        }
3267
3268        int i = mProcessObservers.beginBroadcast();
3269        while (i > 0) {
3270            i--;
3271            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3272            if (observer != null) {
3273                try {
3274                    for (int j=0; j<N; j++) {
3275                        ProcessChangeItem item = mActiveProcessChanges[j];
3276                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3277                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3278                                    + item.pid + " uid=" + item.uid + ": "
3279                                    + item.foregroundActivities);
3280                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3281                                    item.foregroundActivities);
3282                        }
3283                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3284                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3285                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3286                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3287                        }
3288                    }
3289                } catch (RemoteException e) {
3290                }
3291            }
3292        }
3293        mProcessObservers.finishBroadcast();
3294    }
3295
3296    private void dispatchProcessDied(int pid, int uid) {
3297        int i = mProcessObservers.beginBroadcast();
3298        while (i > 0) {
3299            i--;
3300            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3301            if (observer != null) {
3302                try {
3303                    observer.onProcessDied(pid, uid);
3304                } catch (RemoteException e) {
3305                }
3306            }
3307        }
3308        mProcessObservers.finishBroadcast();
3309    }
3310
3311    final void doPendingActivityLaunchesLocked(boolean doResume) {
3312        final int N = mPendingActivityLaunches.size();
3313        if (N <= 0) {
3314            return;
3315        }
3316        for (int i=0; i<N; i++) {
3317            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3318            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
3319                    doResume && i == (N-1), null);
3320        }
3321        mPendingActivityLaunches.clear();
3322    }
3323
3324    @Override
3325    public final int startActivity(IApplicationThread caller, String callingPackage,
3326            Intent intent, String resolvedType, IBinder resultTo,
3327            String resultWho, int requestCode, int startFlags,
3328            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3329        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3330                resultWho, requestCode,
3331                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3332    }
3333
3334    @Override
3335    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3336            Intent intent, String resolvedType, IBinder resultTo,
3337            String resultWho, int requestCode, int startFlags,
3338            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3339        enforceNotIsolatedCaller("startActivity");
3340        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3341                false, true, "startActivity", null);
3342        // TODO: Switch to user app stacks here.
3343        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3344                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3345                null, null, options, userId, null);
3346    }
3347
3348    @Override
3349    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3350            Intent intent, String resolvedType, IBinder resultTo,
3351            String resultWho, int requestCode, int startFlags, String profileFile,
3352            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3353        enforceNotIsolatedCaller("startActivityAndWait");
3354        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3355                false, true, "startActivityAndWait", null);
3356        WaitResult res = new WaitResult();
3357        // TODO: Switch to user app stacks here.
3358        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3359                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3360                res, null, options, UserHandle.getCallingUserId(), null);
3361        return res;
3362    }
3363
3364    @Override
3365    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3366            Intent intent, String resolvedType, IBinder resultTo,
3367            String resultWho, int requestCode, int startFlags, Configuration config,
3368            Bundle options, int userId) {
3369        enforceNotIsolatedCaller("startActivityWithConfig");
3370        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3371                false, true, "startActivityWithConfig", null);
3372        // TODO: Switch to user app stacks here.
3373        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3374                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3375                null, null, null, config, options, userId, null);
3376        return ret;
3377    }
3378
3379    @Override
3380    public int startActivityIntentSender(IApplicationThread caller,
3381            IntentSender intent, Intent fillInIntent, String resolvedType,
3382            IBinder resultTo, String resultWho, int requestCode,
3383            int flagsMask, int flagsValues, Bundle options) {
3384        enforceNotIsolatedCaller("startActivityIntentSender");
3385        // Refuse possible leaked file descriptors
3386        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3387            throw new IllegalArgumentException("File descriptors passed in Intent");
3388        }
3389
3390        IIntentSender sender = intent.getTarget();
3391        if (!(sender instanceof PendingIntentRecord)) {
3392            throw new IllegalArgumentException("Bad PendingIntent object");
3393        }
3394
3395        PendingIntentRecord pir = (PendingIntentRecord)sender;
3396
3397        synchronized (this) {
3398            // If this is coming from the currently resumed activity, it is
3399            // effectively saying that app switches are allowed at this point.
3400            final ActivityStack stack = getFocusedStack();
3401            if (stack.mResumedActivity != null &&
3402                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3403                mAppSwitchesAllowedTime = 0;
3404            }
3405        }
3406        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3407                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3408        return ret;
3409    }
3410
3411    @Override
3412    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3413            Intent intent, String resolvedType, IVoiceInteractionSession session,
3414            IVoiceInteractor interactor, int startFlags, String profileFile,
3415            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3416        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3417                != PackageManager.PERMISSION_GRANTED) {
3418            String msg = "Permission Denial: startVoiceActivity() from pid="
3419                    + Binder.getCallingPid()
3420                    + ", uid=" + Binder.getCallingUid()
3421                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3422            Slog.w(TAG, msg);
3423            throw new SecurityException(msg);
3424        }
3425        if (session == null || interactor == null) {
3426            throw new NullPointerException("null session or interactor");
3427        }
3428        userId = handleIncomingUser(callingPid, callingUid, userId,
3429                false, true, "startVoiceActivity", null);
3430        // TODO: Switch to user app stacks here.
3431        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3432                resolvedType, session, interactor, null, null, 0, startFlags,
3433                profileFile, profileFd, null, null, options, userId, null);
3434    }
3435
3436    @Override
3437    public boolean startNextMatchingActivity(IBinder callingActivity,
3438            Intent intent, Bundle options) {
3439        // Refuse possible leaked file descriptors
3440        if (intent != null && intent.hasFileDescriptors() == true) {
3441            throw new IllegalArgumentException("File descriptors passed in Intent");
3442        }
3443
3444        synchronized (this) {
3445            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3446            if (r == null) {
3447                ActivityOptions.abort(options);
3448                return false;
3449            }
3450            if (r.app == null || r.app.thread == null) {
3451                // The caller is not running...  d'oh!
3452                ActivityOptions.abort(options);
3453                return false;
3454            }
3455            intent = new Intent(intent);
3456            // The caller is not allowed to change the data.
3457            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3458            // And we are resetting to find the next component...
3459            intent.setComponent(null);
3460
3461            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3462
3463            ActivityInfo aInfo = null;
3464            try {
3465                List<ResolveInfo> resolves =
3466                    AppGlobals.getPackageManager().queryIntentActivities(
3467                            intent, r.resolvedType,
3468                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3469                            UserHandle.getCallingUserId());
3470
3471                // Look for the original activity in the list...
3472                final int N = resolves != null ? resolves.size() : 0;
3473                for (int i=0; i<N; i++) {
3474                    ResolveInfo rInfo = resolves.get(i);
3475                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3476                            && rInfo.activityInfo.name.equals(r.info.name)) {
3477                        // We found the current one...  the next matching is
3478                        // after it.
3479                        i++;
3480                        if (i<N) {
3481                            aInfo = resolves.get(i).activityInfo;
3482                        }
3483                        if (debug) {
3484                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3485                                    + "/" + r.info.name);
3486                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3487                                    + "/" + aInfo.name);
3488                        }
3489                        break;
3490                    }
3491                }
3492            } catch (RemoteException e) {
3493            }
3494
3495            if (aInfo == null) {
3496                // Nobody who is next!
3497                ActivityOptions.abort(options);
3498                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3499                return false;
3500            }
3501
3502            intent.setComponent(new ComponentName(
3503                    aInfo.applicationInfo.packageName, aInfo.name));
3504            intent.setFlags(intent.getFlags()&~(
3505                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3506                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3507                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3508                    Intent.FLAG_ACTIVITY_NEW_TASK));
3509
3510            // Okay now we need to start the new activity, replacing the
3511            // currently running activity.  This is a little tricky because
3512            // we want to start the new one as if the current one is finished,
3513            // but not finish the current one first so that there is no flicker.
3514            // And thus...
3515            final boolean wasFinishing = r.finishing;
3516            r.finishing = true;
3517
3518            // Propagate reply information over to the new activity.
3519            final ActivityRecord resultTo = r.resultTo;
3520            final String resultWho = r.resultWho;
3521            final int requestCode = r.requestCode;
3522            r.resultTo = null;
3523            if (resultTo != null) {
3524                resultTo.removeResultsLocked(r, resultWho, requestCode);
3525            }
3526
3527            final long origId = Binder.clearCallingIdentity();
3528            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3529                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3530                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3531                    options, false, null, null);
3532            Binder.restoreCallingIdentity(origId);
3533
3534            r.finishing = wasFinishing;
3535            if (res != ActivityManager.START_SUCCESS) {
3536                return false;
3537            }
3538            return true;
3539        }
3540    }
3541
3542    final int startActivityInPackage(int uid, String callingPackage,
3543            Intent intent, String resolvedType, IBinder resultTo,
3544            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3545                    IActivityContainer container) {
3546
3547        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3548                false, true, "startActivityInPackage", null);
3549
3550        // TODO: Switch to user app stacks here.
3551        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3552                null, null, resultTo, resultWho, requestCode, startFlags,
3553                null, null, null, null, options, userId, container);
3554        return ret;
3555    }
3556
3557    @Override
3558    public final int startActivities(IApplicationThread caller, String callingPackage,
3559            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3560            int userId) {
3561        enforceNotIsolatedCaller("startActivities");
3562        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3563                false, true, "startActivity", null);
3564        // TODO: Switch to user app stacks here.
3565        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3566                resolvedTypes, resultTo, options, userId);
3567        return ret;
3568    }
3569
3570    final int startActivitiesInPackage(int uid, String callingPackage,
3571            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3572            Bundle options, int userId) {
3573
3574        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3575                false, true, "startActivityInPackage", null);
3576        // TODO: Switch to user app stacks here.
3577        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3578                resultTo, options, userId);
3579        return ret;
3580    }
3581
3582    final void addRecentTaskLocked(TaskRecord task) {
3583        int N = mRecentTasks.size();
3584        // Quick case: check if the top-most recent task is the same.
3585        if (N > 0 && mRecentTasks.get(0) == task) {
3586            return;
3587        }
3588        // Another quick case: never add voice sessions.
3589        if (task.voiceSession != null) {
3590            return;
3591        }
3592        // Remove any existing entries that are the same kind of task.
3593        final Intent intent = task.intent;
3594        final boolean document = intent != null && intent.isDocument();
3595        final ComponentName comp = intent.getComponent();
3596
3597        int maxRecents = task.maxRecents - 1;
3598        for (int i=0; i<N; i++) {
3599            TaskRecord tr = mRecentTasks.get(i);
3600            if (task != tr) {
3601                if (task.userId != tr.userId) {
3602                    continue;
3603                }
3604                if (i > MAX_RECENT_BITMAPS) {
3605                    tr.freeLastThumbnail();
3606                }
3607                final Intent trIntent = tr.intent;
3608                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3609                    (intent == null || !intent.filterEquals(trIntent))) {
3610                    continue;
3611                }
3612                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3613                if (document && trIsDocument) {
3614                    // These are the same document activity (not necessarily the same doc).
3615                    if (maxRecents > 0) {
3616                        --maxRecents;
3617                        continue;
3618                    }
3619                    // Hit the maximum number of documents for this task. Fall through
3620                    // and remove this document from recents.
3621                } else if (document || trIsDocument) {
3622                    // Only one of these is a document. Not the droid we're looking for.
3623                    continue;
3624                }
3625            }
3626
3627            // Either task and tr are the same or, their affinities match or their intents match
3628            // and neither of them is a document, or they are documents using the same activity
3629            // and their maxRecents has been reached.
3630            tr.disposeThumbnail();
3631            mRecentTasks.remove(i);
3632            i--;
3633            N--;
3634            if (task.intent == null) {
3635                // If the new recent task we are adding is not fully
3636                // specified, then replace it with the existing recent task.
3637                task = tr;
3638            }
3639            mTaskPersister.notify(tr, false);
3640        }
3641        if (N >= MAX_RECENT_TASKS) {
3642            mRecentTasks.remove(N-1).disposeThumbnail();
3643        }
3644        mRecentTasks.add(0, task);
3645    }
3646
3647    @Override
3648    public void reportActivityFullyDrawn(IBinder token) {
3649        synchronized (this) {
3650            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3651            if (r == null) {
3652                return;
3653            }
3654            r.reportFullyDrawnLocked();
3655        }
3656    }
3657
3658    @Override
3659    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3660        synchronized (this) {
3661            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3662            if (r == null) {
3663                return;
3664            }
3665            final long origId = Binder.clearCallingIdentity();
3666            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3667            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3668                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3669            if (config != null) {
3670                r.frozenBeforeDestroy = true;
3671                if (!updateConfigurationLocked(config, r, false, false)) {
3672                    mStackSupervisor.resumeTopActivitiesLocked();
3673                }
3674            }
3675            Binder.restoreCallingIdentity(origId);
3676        }
3677    }
3678
3679    @Override
3680    public int getRequestedOrientation(IBinder token) {
3681        synchronized (this) {
3682            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3683            if (r == null) {
3684                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3685            }
3686            return mWindowManager.getAppOrientation(r.appToken);
3687        }
3688    }
3689
3690    /**
3691     * This is the internal entry point for handling Activity.finish().
3692     *
3693     * @param token The Binder token referencing the Activity we want to finish.
3694     * @param resultCode Result code, if any, from this Activity.
3695     * @param resultData Result data (Intent), if any, from this Activity.
3696     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3697     *            the root Activity in the task.
3698     *
3699     * @return Returns true if the activity successfully finished, or false if it is still running.
3700     */
3701    @Override
3702    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3703            boolean finishTask) {
3704        // Refuse possible leaked file descriptors
3705        if (resultData != null && resultData.hasFileDescriptors() == true) {
3706            throw new IllegalArgumentException("File descriptors passed in Intent");
3707        }
3708
3709        synchronized(this) {
3710            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3711            if (r == null) {
3712                return true;
3713            }
3714            // Keep track of the root activity of the task before we finish it
3715            TaskRecord tr = r.task;
3716            ActivityRecord rootR = tr.getRootActivity();
3717            // Do not allow task to finish in Lock Task mode.
3718            if (tr == mStackSupervisor.mLockTaskModeTask) {
3719                if (rootR == r) {
3720                    mStackSupervisor.showLockTaskToast();
3721                    return false;
3722                }
3723            }
3724            if (mController != null) {
3725                // Find the first activity that is not finishing.
3726                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3727                if (next != null) {
3728                    // ask watcher if this is allowed
3729                    boolean resumeOK = true;
3730                    try {
3731                        resumeOK = mController.activityResuming(next.packageName);
3732                    } catch (RemoteException e) {
3733                        mController = null;
3734                        Watchdog.getInstance().setActivityController(null);
3735                    }
3736
3737                    if (!resumeOK) {
3738                        return false;
3739                    }
3740                }
3741            }
3742            final long origId = Binder.clearCallingIdentity();
3743            try {
3744                boolean res;
3745                if (finishTask && r == rootR) {
3746                    // If requested, remove the task that is associated to this activity only if it
3747                    // was the root activity in the task.  The result code and data is ignored because
3748                    // we don't support returning them across task boundaries.
3749                    res = removeTaskByIdLocked(tr.taskId, 0);
3750                } else {
3751                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3752                            resultData, "app-request", true);
3753                }
3754                return res;
3755            } finally {
3756                Binder.restoreCallingIdentity(origId);
3757            }
3758        }
3759    }
3760
3761    @Override
3762    public final void finishHeavyWeightApp() {
3763        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3764                != PackageManager.PERMISSION_GRANTED) {
3765            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3766                    + Binder.getCallingPid()
3767                    + ", uid=" + Binder.getCallingUid()
3768                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3769            Slog.w(TAG, msg);
3770            throw new SecurityException(msg);
3771        }
3772
3773        synchronized(this) {
3774            if (mHeavyWeightProcess == null) {
3775                return;
3776            }
3777
3778            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3779                    mHeavyWeightProcess.activities);
3780            for (int i=0; i<activities.size(); i++) {
3781                ActivityRecord r = activities.get(i);
3782                if (!r.finishing) {
3783                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3784                            null, "finish-heavy", true);
3785                }
3786            }
3787
3788            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3789                    mHeavyWeightProcess.userId, 0));
3790            mHeavyWeightProcess = null;
3791        }
3792    }
3793
3794    @Override
3795    public void crashApplication(int uid, int initialPid, String packageName,
3796            String message) {
3797        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3798                != PackageManager.PERMISSION_GRANTED) {
3799            String msg = "Permission Denial: crashApplication() from pid="
3800                    + Binder.getCallingPid()
3801                    + ", uid=" + Binder.getCallingUid()
3802                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3803            Slog.w(TAG, msg);
3804            throw new SecurityException(msg);
3805        }
3806
3807        synchronized(this) {
3808            ProcessRecord proc = null;
3809
3810            // Figure out which process to kill.  We don't trust that initialPid
3811            // still has any relation to current pids, so must scan through the
3812            // list.
3813            synchronized (mPidsSelfLocked) {
3814                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3815                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3816                    if (p.uid != uid) {
3817                        continue;
3818                    }
3819                    if (p.pid == initialPid) {
3820                        proc = p;
3821                        break;
3822                    }
3823                    if (p.pkgList.containsKey(packageName)) {
3824                        proc = p;
3825                    }
3826                }
3827            }
3828
3829            if (proc == null) {
3830                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3831                        + " initialPid=" + initialPid
3832                        + " packageName=" + packageName);
3833                return;
3834            }
3835
3836            if (proc.thread != null) {
3837                if (proc.pid == Process.myPid()) {
3838                    Log.w(TAG, "crashApplication: trying to crash self!");
3839                    return;
3840                }
3841                long ident = Binder.clearCallingIdentity();
3842                try {
3843                    proc.thread.scheduleCrash(message);
3844                } catch (RemoteException e) {
3845                }
3846                Binder.restoreCallingIdentity(ident);
3847            }
3848        }
3849    }
3850
3851    @Override
3852    public final void finishSubActivity(IBinder token, String resultWho,
3853            int requestCode) {
3854        synchronized(this) {
3855            final long origId = Binder.clearCallingIdentity();
3856            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3857            if (r != null) {
3858                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3859            }
3860            Binder.restoreCallingIdentity(origId);
3861        }
3862    }
3863
3864    @Override
3865    public boolean finishActivityAffinity(IBinder token) {
3866        synchronized(this) {
3867            final long origId = Binder.clearCallingIdentity();
3868            try {
3869                ActivityRecord r = ActivityRecord.isInStackLocked(token);
3870
3871                ActivityRecord rootR = r.task.getRootActivity();
3872                // Do not allow task to finish in Lock Task mode.
3873                if (r.task == mStackSupervisor.mLockTaskModeTask) {
3874                    if (rootR == r) {
3875                        mStackSupervisor.showLockTaskToast();
3876                        return false;
3877                    }
3878                }
3879                boolean res = false;
3880                if (r != null) {
3881                    res = r.task.stack.finishActivityAffinityLocked(r);
3882                }
3883                return res;
3884            } finally {
3885                Binder.restoreCallingIdentity(origId);
3886            }
3887        }
3888    }
3889
3890    @Override
3891    public void finishVoiceTask(IVoiceInteractionSession session) {
3892        synchronized(this) {
3893            final long origId = Binder.clearCallingIdentity();
3894            try {
3895                mStackSupervisor.finishVoiceTask(session);
3896            } finally {
3897                Binder.restoreCallingIdentity(origId);
3898            }
3899        }
3900
3901    }
3902
3903    @Override
3904    public boolean willActivityBeVisible(IBinder token) {
3905        synchronized(this) {
3906            ActivityStack stack = ActivityRecord.getStackLocked(token);
3907            if (stack != null) {
3908                return stack.willActivityBeVisibleLocked(token);
3909            }
3910            return false;
3911        }
3912    }
3913
3914    @Override
3915    public void overridePendingTransition(IBinder token, String packageName,
3916            int enterAnim, int exitAnim) {
3917        synchronized(this) {
3918            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3919            if (self == null) {
3920                return;
3921            }
3922
3923            final long origId = Binder.clearCallingIdentity();
3924
3925            if (self.state == ActivityState.RESUMED
3926                    || self.state == ActivityState.PAUSING) {
3927                mWindowManager.overridePendingAppTransition(packageName,
3928                        enterAnim, exitAnim, null);
3929            }
3930
3931            Binder.restoreCallingIdentity(origId);
3932        }
3933    }
3934
3935    /**
3936     * Main function for removing an existing process from the activity manager
3937     * as a result of that process going away.  Clears out all connections
3938     * to the process.
3939     */
3940    private final void handleAppDiedLocked(ProcessRecord app,
3941            boolean restarting, boolean allowRestart) {
3942        int pid = app.pid;
3943        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3944        if (!restarting) {
3945            removeLruProcessLocked(app);
3946            if (pid > 0) {
3947                ProcessList.remove(pid);
3948            }
3949        }
3950
3951        if (mProfileProc == app) {
3952            clearProfilerLocked();
3953        }
3954
3955        // Remove this application's activities from active lists.
3956        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3957
3958        app.activities.clear();
3959
3960        if (app.instrumentationClass != null) {
3961            Slog.w(TAG, "Crash of app " + app.processName
3962                  + " running instrumentation " + app.instrumentationClass);
3963            Bundle info = new Bundle();
3964            info.putString("shortMsg", "Process crashed.");
3965            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3966        }
3967
3968        if (!restarting) {
3969            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3970                // If there was nothing to resume, and we are not already
3971                // restarting this process, but there is a visible activity that
3972                // is hosted by the process...  then make sure all visible
3973                // activities are running, taking care of restarting this
3974                // process.
3975                if (hasVisibleActivities) {
3976                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3977                }
3978            }
3979        }
3980    }
3981
3982    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3983        IBinder threadBinder = thread.asBinder();
3984        // Find the application record.
3985        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3986            ProcessRecord rec = mLruProcesses.get(i);
3987            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3988                return i;
3989            }
3990        }
3991        return -1;
3992    }
3993
3994    final ProcessRecord getRecordForAppLocked(
3995            IApplicationThread thread) {
3996        if (thread == null) {
3997            return null;
3998        }
3999
4000        int appIndex = getLRURecordIndexForAppLocked(thread);
4001        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4002    }
4003
4004    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4005        // If there are no longer any background processes running,
4006        // and the app that died was not running instrumentation,
4007        // then tell everyone we are now low on memory.
4008        boolean haveBg = false;
4009        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4010            ProcessRecord rec = mLruProcesses.get(i);
4011            if (rec.thread != null
4012                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4013                haveBg = true;
4014                break;
4015            }
4016        }
4017
4018        if (!haveBg) {
4019            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4020            if (doReport) {
4021                long now = SystemClock.uptimeMillis();
4022                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4023                    doReport = false;
4024                } else {
4025                    mLastMemUsageReportTime = now;
4026                }
4027            }
4028            final ArrayList<ProcessMemInfo> memInfos
4029                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4030            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4031            long now = SystemClock.uptimeMillis();
4032            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4033                ProcessRecord rec = mLruProcesses.get(i);
4034                if (rec == dyingProc || rec.thread == null) {
4035                    continue;
4036                }
4037                if (doReport) {
4038                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4039                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4040                }
4041                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4042                    // The low memory report is overriding any current
4043                    // state for a GC request.  Make sure to do
4044                    // heavy/important/visible/foreground processes first.
4045                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4046                        rec.lastRequestedGc = 0;
4047                    } else {
4048                        rec.lastRequestedGc = rec.lastLowMemory;
4049                    }
4050                    rec.reportLowMemory = true;
4051                    rec.lastLowMemory = now;
4052                    mProcessesToGc.remove(rec);
4053                    addProcessToGcListLocked(rec);
4054                }
4055            }
4056            if (doReport) {
4057                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4058                mHandler.sendMessage(msg);
4059            }
4060            scheduleAppGcsLocked();
4061        }
4062    }
4063
4064    final void appDiedLocked(ProcessRecord app, int pid,
4065            IApplicationThread thread) {
4066
4067        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4068        synchronized (stats) {
4069            stats.noteProcessDiedLocked(app.info.uid, pid);
4070        }
4071
4072        // Clean up already done if the process has been re-started.
4073        if (app.pid == pid && app.thread != null &&
4074                app.thread.asBinder() == thread.asBinder()) {
4075            boolean doLowMem = app.instrumentationClass == null;
4076            boolean doOomAdj = doLowMem;
4077            if (!app.killedByAm) {
4078                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4079                        + ") has died.");
4080                mAllowLowerMemLevel = true;
4081            } else {
4082                // Note that we always want to do oom adj to update our state with the
4083                // new number of procs.
4084                mAllowLowerMemLevel = false;
4085                doLowMem = false;
4086            }
4087            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4088            if (DEBUG_CLEANUP) Slog.v(
4089                TAG, "Dying app: " + app + ", pid: " + pid
4090                + ", thread: " + thread.asBinder());
4091            handleAppDiedLocked(app, false, true);
4092
4093            if (doOomAdj) {
4094                updateOomAdjLocked();
4095            }
4096            if (doLowMem) {
4097                doLowMemReportIfNeededLocked(app);
4098            }
4099        } else if (app.pid != pid) {
4100            // A new process has already been started.
4101            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4102                    + ") has died and restarted (pid " + app.pid + ").");
4103            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4104        } else if (DEBUG_PROCESSES) {
4105            Slog.d(TAG, "Received spurious death notification for thread "
4106                    + thread.asBinder());
4107        }
4108    }
4109
4110    /**
4111     * If a stack trace dump file is configured, dump process stack traces.
4112     * @param clearTraces causes the dump file to be erased prior to the new
4113     *    traces being written, if true; when false, the new traces will be
4114     *    appended to any existing file content.
4115     * @param firstPids of dalvik VM processes to dump stack traces for first
4116     * @param lastPids of dalvik VM processes to dump stack traces for last
4117     * @param nativeProcs optional list of native process names to dump stack crawls
4118     * @return file containing stack traces, or null if no dump file is configured
4119     */
4120    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4121            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4122        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4123        if (tracesPath == null || tracesPath.length() == 0) {
4124            return null;
4125        }
4126
4127        File tracesFile = new File(tracesPath);
4128        try {
4129            File tracesDir = tracesFile.getParentFile();
4130            if (!tracesDir.exists()) {
4131                tracesFile.mkdirs();
4132                if (!SELinux.restorecon(tracesDir)) {
4133                    return null;
4134                }
4135            }
4136            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4137
4138            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4139            tracesFile.createNewFile();
4140            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4141        } catch (IOException e) {
4142            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4143            return null;
4144        }
4145
4146        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4147        return tracesFile;
4148    }
4149
4150    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4151            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4152        // Use a FileObserver to detect when traces finish writing.
4153        // The order of traces is considered important to maintain for legibility.
4154        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4155            @Override
4156            public synchronized void onEvent(int event, String path) { notify(); }
4157        };
4158
4159        try {
4160            observer.startWatching();
4161
4162            // First collect all of the stacks of the most important pids.
4163            if (firstPids != null) {
4164                try {
4165                    int num = firstPids.size();
4166                    for (int i = 0; i < num; i++) {
4167                        synchronized (observer) {
4168                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4169                            observer.wait(200);  // Wait for write-close, give up after 200msec
4170                        }
4171                    }
4172                } catch (InterruptedException e) {
4173                    Log.wtf(TAG, e);
4174                }
4175            }
4176
4177            // Next collect the stacks of the native pids
4178            if (nativeProcs != null) {
4179                int[] pids = Process.getPidsForCommands(nativeProcs);
4180                if (pids != null) {
4181                    for (int pid : pids) {
4182                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4183                    }
4184                }
4185            }
4186
4187            // Lastly, measure CPU usage.
4188            if (processCpuTracker != null) {
4189                processCpuTracker.init();
4190                System.gc();
4191                processCpuTracker.update();
4192                try {
4193                    synchronized (processCpuTracker) {
4194                        processCpuTracker.wait(500); // measure over 1/2 second.
4195                    }
4196                } catch (InterruptedException e) {
4197                }
4198                processCpuTracker.update();
4199
4200                // We'll take the stack crawls of just the top apps using CPU.
4201                final int N = processCpuTracker.countWorkingStats();
4202                int numProcs = 0;
4203                for (int i=0; i<N && numProcs<5; i++) {
4204                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4205                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4206                        numProcs++;
4207                        try {
4208                            synchronized (observer) {
4209                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4210                                observer.wait(200);  // Wait for write-close, give up after 200msec
4211                            }
4212                        } catch (InterruptedException e) {
4213                            Log.wtf(TAG, e);
4214                        }
4215
4216                    }
4217                }
4218            }
4219        } finally {
4220            observer.stopWatching();
4221        }
4222    }
4223
4224    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4225        if (true || IS_USER_BUILD) {
4226            return;
4227        }
4228        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4229        if (tracesPath == null || tracesPath.length() == 0) {
4230            return;
4231        }
4232
4233        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4234        StrictMode.allowThreadDiskWrites();
4235        try {
4236            final File tracesFile = new File(tracesPath);
4237            final File tracesDir = tracesFile.getParentFile();
4238            final File tracesTmp = new File(tracesDir, "__tmp__");
4239            try {
4240                if (!tracesDir.exists()) {
4241                    tracesFile.mkdirs();
4242                    if (!SELinux.restorecon(tracesDir.getPath())) {
4243                        return;
4244                    }
4245                }
4246                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4247
4248                if (tracesFile.exists()) {
4249                    tracesTmp.delete();
4250                    tracesFile.renameTo(tracesTmp);
4251                }
4252                StringBuilder sb = new StringBuilder();
4253                Time tobj = new Time();
4254                tobj.set(System.currentTimeMillis());
4255                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4256                sb.append(": ");
4257                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4258                sb.append(" since ");
4259                sb.append(msg);
4260                FileOutputStream fos = new FileOutputStream(tracesFile);
4261                fos.write(sb.toString().getBytes());
4262                if (app == null) {
4263                    fos.write("\n*** No application process!".getBytes());
4264                }
4265                fos.close();
4266                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4267            } catch (IOException e) {
4268                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4269                return;
4270            }
4271
4272            if (app != null) {
4273                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4274                firstPids.add(app.pid);
4275                dumpStackTraces(tracesPath, firstPids, null, null, null);
4276            }
4277
4278            File lastTracesFile = null;
4279            File curTracesFile = null;
4280            for (int i=9; i>=0; i--) {
4281                String name = String.format(Locale.US, "slow%02d.txt", i);
4282                curTracesFile = new File(tracesDir, name);
4283                if (curTracesFile.exists()) {
4284                    if (lastTracesFile != null) {
4285                        curTracesFile.renameTo(lastTracesFile);
4286                    } else {
4287                        curTracesFile.delete();
4288                    }
4289                }
4290                lastTracesFile = curTracesFile;
4291            }
4292            tracesFile.renameTo(curTracesFile);
4293            if (tracesTmp.exists()) {
4294                tracesTmp.renameTo(tracesFile);
4295            }
4296        } finally {
4297            StrictMode.setThreadPolicy(oldPolicy);
4298        }
4299    }
4300
4301    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4302            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4303        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4304        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4305
4306        if (mController != null) {
4307            try {
4308                // 0 == continue, -1 = kill process immediately
4309                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4310                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
4311            } catch (RemoteException e) {
4312                mController = null;
4313                Watchdog.getInstance().setActivityController(null);
4314            }
4315        }
4316
4317        long anrTime = SystemClock.uptimeMillis();
4318        if (MONITOR_CPU_USAGE) {
4319            updateCpuStatsNow();
4320        }
4321
4322        synchronized (this) {
4323            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4324            if (mShuttingDown) {
4325                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4326                return;
4327            } else if (app.notResponding) {
4328                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4329                return;
4330            } else if (app.crashing) {
4331                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4332                return;
4333            }
4334
4335            // In case we come through here for the same app before completing
4336            // this one, mark as anring now so we will bail out.
4337            app.notResponding = true;
4338
4339            // Log the ANR to the event log.
4340            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4341                    app.processName, app.info.flags, annotation);
4342
4343            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4344            firstPids.add(app.pid);
4345
4346            int parentPid = app.pid;
4347            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4348            if (parentPid != app.pid) firstPids.add(parentPid);
4349
4350            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4351
4352            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4353                ProcessRecord r = mLruProcesses.get(i);
4354                if (r != null && r.thread != null) {
4355                    int pid = r.pid;
4356                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4357                        if (r.persistent) {
4358                            firstPids.add(pid);
4359                        } else {
4360                            lastPids.put(pid, Boolean.TRUE);
4361                        }
4362                    }
4363                }
4364            }
4365        }
4366
4367        // Log the ANR to the main log.
4368        StringBuilder info = new StringBuilder();
4369        info.setLength(0);
4370        info.append("ANR in ").append(app.processName);
4371        if (activity != null && activity.shortComponentName != null) {
4372            info.append(" (").append(activity.shortComponentName).append(")");
4373        }
4374        info.append("\n");
4375        info.append("PID: ").append(app.pid).append("\n");
4376        if (annotation != null) {
4377            info.append("Reason: ").append(annotation).append("\n");
4378        }
4379        if (parent != null && parent != activity) {
4380            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4381        }
4382
4383        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4384
4385        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4386                NATIVE_STACKS_OF_INTEREST);
4387
4388        String cpuInfo = null;
4389        if (MONITOR_CPU_USAGE) {
4390            updateCpuStatsNow();
4391            synchronized (mProcessCpuThread) {
4392                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4393            }
4394            info.append(processCpuTracker.printCurrentLoad());
4395            info.append(cpuInfo);
4396        }
4397
4398        info.append(processCpuTracker.printCurrentState(anrTime));
4399
4400        Slog.e(TAG, info.toString());
4401        if (tracesFile == null) {
4402            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4403            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4404        }
4405
4406        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4407                cpuInfo, tracesFile, null);
4408
4409        if (mController != null) {
4410            try {
4411                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4412                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4413                if (res != 0) {
4414                    if (res < 0 && app.pid != MY_PID) {
4415                        Process.killProcess(app.pid);
4416                    } else {
4417                        synchronized (this) {
4418                            mServices.scheduleServiceTimeoutLocked(app);
4419                        }
4420                    }
4421                    return;
4422                }
4423            } catch (RemoteException e) {
4424                mController = null;
4425                Watchdog.getInstance().setActivityController(null);
4426            }
4427        }
4428
4429        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4430        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4431                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4432
4433        synchronized (this) {
4434            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4435                killUnneededProcessLocked(app, "background ANR");
4436                return;
4437            }
4438
4439            // Set the app's notResponding state, and look up the errorReportReceiver
4440            makeAppNotRespondingLocked(app,
4441                    activity != null ? activity.shortComponentName : null,
4442                    annotation != null ? "ANR " + annotation : "ANR",
4443                    info.toString());
4444
4445            // Bring up the infamous App Not Responding dialog
4446            Message msg = Message.obtain();
4447            HashMap<String, Object> map = new HashMap<String, Object>();
4448            msg.what = SHOW_NOT_RESPONDING_MSG;
4449            msg.obj = map;
4450            msg.arg1 = aboveSystem ? 1 : 0;
4451            map.put("app", app);
4452            if (activity != null) {
4453                map.put("activity", activity);
4454            }
4455
4456            mHandler.sendMessage(msg);
4457        }
4458    }
4459
4460    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4461        if (!mLaunchWarningShown) {
4462            mLaunchWarningShown = true;
4463            mHandler.post(new Runnable() {
4464                @Override
4465                public void run() {
4466                    synchronized (ActivityManagerService.this) {
4467                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4468                        d.show();
4469                        mHandler.postDelayed(new Runnable() {
4470                            @Override
4471                            public void run() {
4472                                synchronized (ActivityManagerService.this) {
4473                                    d.dismiss();
4474                                    mLaunchWarningShown = false;
4475                                }
4476                            }
4477                        }, 4000);
4478                    }
4479                }
4480            });
4481        }
4482    }
4483
4484    @Override
4485    public boolean clearApplicationUserData(final String packageName,
4486            final IPackageDataObserver observer, int userId) {
4487        enforceNotIsolatedCaller("clearApplicationUserData");
4488        int uid = Binder.getCallingUid();
4489        int pid = Binder.getCallingPid();
4490        userId = handleIncomingUser(pid, uid,
4491                userId, false, true, "clearApplicationUserData", null);
4492        long callingId = Binder.clearCallingIdentity();
4493        try {
4494            IPackageManager pm = AppGlobals.getPackageManager();
4495            int pkgUid = -1;
4496            synchronized(this) {
4497                try {
4498                    pkgUid = pm.getPackageUid(packageName, userId);
4499                } catch (RemoteException e) {
4500                }
4501                if (pkgUid == -1) {
4502                    Slog.w(TAG, "Invalid packageName: " + packageName);
4503                    if (observer != null) {
4504                        try {
4505                            observer.onRemoveCompleted(packageName, false);
4506                        } catch (RemoteException e) {
4507                            Slog.i(TAG, "Observer no longer exists.");
4508                        }
4509                    }
4510                    return false;
4511                }
4512                if (uid == pkgUid || checkComponentPermission(
4513                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4514                        pid, uid, -1, true)
4515                        == PackageManager.PERMISSION_GRANTED) {
4516                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4517                } else {
4518                    throw new SecurityException("PID " + pid + " does not have permission "
4519                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4520                                    + " of package " + packageName);
4521                }
4522            }
4523
4524            try {
4525                // Clear application user data
4526                pm.clearApplicationUserData(packageName, observer, userId);
4527
4528                // Remove all permissions granted from/to this package
4529                removeUriPermissionsForPackageLocked(packageName, userId, true);
4530
4531                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4532                        Uri.fromParts("package", packageName, null));
4533                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4534                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4535                        null, null, 0, null, null, null, false, false, userId);
4536            } catch (RemoteException e) {
4537            }
4538        } finally {
4539            Binder.restoreCallingIdentity(callingId);
4540        }
4541        return true;
4542    }
4543
4544    @Override
4545    public void killBackgroundProcesses(final String packageName, int userId) {
4546        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4547                != PackageManager.PERMISSION_GRANTED &&
4548                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4549                        != PackageManager.PERMISSION_GRANTED) {
4550            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4551                    + Binder.getCallingPid()
4552                    + ", uid=" + Binder.getCallingUid()
4553                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4554            Slog.w(TAG, msg);
4555            throw new SecurityException(msg);
4556        }
4557
4558        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4559                userId, true, true, "killBackgroundProcesses", null);
4560        long callingId = Binder.clearCallingIdentity();
4561        try {
4562            IPackageManager pm = AppGlobals.getPackageManager();
4563            synchronized(this) {
4564                int appId = -1;
4565                try {
4566                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4567                } catch (RemoteException e) {
4568                }
4569                if (appId == -1) {
4570                    Slog.w(TAG, "Invalid packageName: " + packageName);
4571                    return;
4572                }
4573                killPackageProcessesLocked(packageName, appId, userId,
4574                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4575            }
4576        } finally {
4577            Binder.restoreCallingIdentity(callingId);
4578        }
4579    }
4580
4581    @Override
4582    public void killAllBackgroundProcesses() {
4583        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4584                != PackageManager.PERMISSION_GRANTED) {
4585            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4586                    + Binder.getCallingPid()
4587                    + ", uid=" + Binder.getCallingUid()
4588                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4589            Slog.w(TAG, msg);
4590            throw new SecurityException(msg);
4591        }
4592
4593        long callingId = Binder.clearCallingIdentity();
4594        try {
4595            synchronized(this) {
4596                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4597                final int NP = mProcessNames.getMap().size();
4598                for (int ip=0; ip<NP; ip++) {
4599                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4600                    final int NA = apps.size();
4601                    for (int ia=0; ia<NA; ia++) {
4602                        ProcessRecord app = apps.valueAt(ia);
4603                        if (app.persistent) {
4604                            // we don't kill persistent processes
4605                            continue;
4606                        }
4607                        if (app.removed) {
4608                            procs.add(app);
4609                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4610                            app.removed = true;
4611                            procs.add(app);
4612                        }
4613                    }
4614                }
4615
4616                int N = procs.size();
4617                for (int i=0; i<N; i++) {
4618                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4619                }
4620                mAllowLowerMemLevel = true;
4621                updateOomAdjLocked();
4622                doLowMemReportIfNeededLocked(null);
4623            }
4624        } finally {
4625            Binder.restoreCallingIdentity(callingId);
4626        }
4627    }
4628
4629    @Override
4630    public void forceStopPackage(final String packageName, int userId) {
4631        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4632                != PackageManager.PERMISSION_GRANTED) {
4633            String msg = "Permission Denial: forceStopPackage() from pid="
4634                    + Binder.getCallingPid()
4635                    + ", uid=" + Binder.getCallingUid()
4636                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4637            Slog.w(TAG, msg);
4638            throw new SecurityException(msg);
4639        }
4640        final int callingPid = Binder.getCallingPid();
4641        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4642                userId, true, true, "forceStopPackage", null);
4643        long callingId = Binder.clearCallingIdentity();
4644        try {
4645            IPackageManager pm = AppGlobals.getPackageManager();
4646            synchronized(this) {
4647                int[] users = userId == UserHandle.USER_ALL
4648                        ? getUsersLocked() : new int[] { userId };
4649                for (int user : users) {
4650                    int pkgUid = -1;
4651                    try {
4652                        pkgUid = pm.getPackageUid(packageName, user);
4653                    } catch (RemoteException e) {
4654                    }
4655                    if (pkgUid == -1) {
4656                        Slog.w(TAG, "Invalid packageName: " + packageName);
4657                        continue;
4658                    }
4659                    try {
4660                        pm.setPackageStoppedState(packageName, true, user);
4661                    } catch (RemoteException e) {
4662                    } catch (IllegalArgumentException e) {
4663                        Slog.w(TAG, "Failed trying to unstop package "
4664                                + packageName + ": " + e);
4665                    }
4666                    if (isUserRunningLocked(user, false)) {
4667                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4668                    }
4669                }
4670            }
4671        } finally {
4672            Binder.restoreCallingIdentity(callingId);
4673        }
4674    }
4675
4676    /*
4677     * The pkg name and app id have to be specified.
4678     */
4679    @Override
4680    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4681        if (pkg == null) {
4682            return;
4683        }
4684        // Make sure the uid is valid.
4685        if (appid < 0) {
4686            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4687            return;
4688        }
4689        int callerUid = Binder.getCallingUid();
4690        // Only the system server can kill an application
4691        if (callerUid == Process.SYSTEM_UID) {
4692            // Post an aysnc message to kill the application
4693            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4694            msg.arg1 = appid;
4695            msg.arg2 = 0;
4696            Bundle bundle = new Bundle();
4697            bundle.putString("pkg", pkg);
4698            bundle.putString("reason", reason);
4699            msg.obj = bundle;
4700            mHandler.sendMessage(msg);
4701        } else {
4702            throw new SecurityException(callerUid + " cannot kill pkg: " +
4703                    pkg);
4704        }
4705    }
4706
4707    @Override
4708    public void closeSystemDialogs(String reason) {
4709        enforceNotIsolatedCaller("closeSystemDialogs");
4710
4711        final int pid = Binder.getCallingPid();
4712        final int uid = Binder.getCallingUid();
4713        final long origId = Binder.clearCallingIdentity();
4714        try {
4715            synchronized (this) {
4716                // Only allow this from foreground processes, so that background
4717                // applications can't abuse it to prevent system UI from being shown.
4718                if (uid >= Process.FIRST_APPLICATION_UID) {
4719                    ProcessRecord proc;
4720                    synchronized (mPidsSelfLocked) {
4721                        proc = mPidsSelfLocked.get(pid);
4722                    }
4723                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4724                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4725                                + " from background process " + proc);
4726                        return;
4727                    }
4728                }
4729                closeSystemDialogsLocked(reason);
4730            }
4731        } finally {
4732            Binder.restoreCallingIdentity(origId);
4733        }
4734    }
4735
4736    void closeSystemDialogsLocked(String reason) {
4737        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4738        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4739                | Intent.FLAG_RECEIVER_FOREGROUND);
4740        if (reason != null) {
4741            intent.putExtra("reason", reason);
4742        }
4743        mWindowManager.closeSystemDialogs(reason);
4744
4745        mStackSupervisor.closeSystemDialogsLocked();
4746
4747        broadcastIntentLocked(null, null, intent, null,
4748                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4749                Process.SYSTEM_UID, UserHandle.USER_ALL);
4750    }
4751
4752    @Override
4753    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4754        enforceNotIsolatedCaller("getProcessMemoryInfo");
4755        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4756        for (int i=pids.length-1; i>=0; i--) {
4757            ProcessRecord proc;
4758            int oomAdj;
4759            synchronized (this) {
4760                synchronized (mPidsSelfLocked) {
4761                    proc = mPidsSelfLocked.get(pids[i]);
4762                    oomAdj = proc != null ? proc.setAdj : 0;
4763                }
4764            }
4765            infos[i] = new Debug.MemoryInfo();
4766            Debug.getMemoryInfo(pids[i], infos[i]);
4767            if (proc != null) {
4768                synchronized (this) {
4769                    if (proc.thread != null && proc.setAdj == oomAdj) {
4770                        // Record this for posterity if the process has been stable.
4771                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4772                                infos[i].getTotalUss(), false, proc.pkgList);
4773                    }
4774                }
4775            }
4776        }
4777        return infos;
4778    }
4779
4780    @Override
4781    public long[] getProcessPss(int[] pids) {
4782        enforceNotIsolatedCaller("getProcessPss");
4783        long[] pss = new long[pids.length];
4784        for (int i=pids.length-1; i>=0; i--) {
4785            ProcessRecord proc;
4786            int oomAdj;
4787            synchronized (this) {
4788                synchronized (mPidsSelfLocked) {
4789                    proc = mPidsSelfLocked.get(pids[i]);
4790                    oomAdj = proc != null ? proc.setAdj : 0;
4791                }
4792            }
4793            long[] tmpUss = new long[1];
4794            pss[i] = Debug.getPss(pids[i], tmpUss);
4795            if (proc != null) {
4796                synchronized (this) {
4797                    if (proc.thread != null && proc.setAdj == oomAdj) {
4798                        // Record this for posterity if the process has been stable.
4799                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4800                    }
4801                }
4802            }
4803        }
4804        return pss;
4805    }
4806
4807    @Override
4808    public void killApplicationProcess(String processName, int uid) {
4809        if (processName == null) {
4810            return;
4811        }
4812
4813        int callerUid = Binder.getCallingUid();
4814        // Only the system server can kill an application
4815        if (callerUid == Process.SYSTEM_UID) {
4816            synchronized (this) {
4817                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4818                if (app != null && app.thread != null) {
4819                    try {
4820                        app.thread.scheduleSuicide();
4821                    } catch (RemoteException e) {
4822                        // If the other end already died, then our work here is done.
4823                    }
4824                } else {
4825                    Slog.w(TAG, "Process/uid not found attempting kill of "
4826                            + processName + " / " + uid);
4827                }
4828            }
4829        } else {
4830            throw new SecurityException(callerUid + " cannot kill app process: " +
4831                    processName);
4832        }
4833    }
4834
4835    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4836        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4837                false, true, false, false, UserHandle.getUserId(uid), reason);
4838        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4839                Uri.fromParts("package", packageName, null));
4840        if (!mProcessesReady) {
4841            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4842                    | Intent.FLAG_RECEIVER_FOREGROUND);
4843        }
4844        intent.putExtra(Intent.EXTRA_UID, uid);
4845        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4846        broadcastIntentLocked(null, null, intent,
4847                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4848                false, false,
4849                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4850    }
4851
4852    private void forceStopUserLocked(int userId, String reason) {
4853        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4854        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4855        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4856                | Intent.FLAG_RECEIVER_FOREGROUND);
4857        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4858        broadcastIntentLocked(null, null, intent,
4859                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4860                false, false,
4861                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4862    }
4863
4864    private final boolean killPackageProcessesLocked(String packageName, int appId,
4865            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4866            boolean doit, boolean evenPersistent, String reason) {
4867        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4868
4869        // Remove all processes this package may have touched: all with the
4870        // same UID (except for the system or root user), and all whose name
4871        // matches the package name.
4872        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4873        final int NP = mProcessNames.getMap().size();
4874        for (int ip=0; ip<NP; ip++) {
4875            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4876            final int NA = apps.size();
4877            for (int ia=0; ia<NA; ia++) {
4878                ProcessRecord app = apps.valueAt(ia);
4879                if (app.persistent && !evenPersistent) {
4880                    // we don't kill persistent processes
4881                    continue;
4882                }
4883                if (app.removed) {
4884                    if (doit) {
4885                        procs.add(app);
4886                    }
4887                    continue;
4888                }
4889
4890                // Skip process if it doesn't meet our oom adj requirement.
4891                if (app.setAdj < minOomAdj) {
4892                    continue;
4893                }
4894
4895                // If no package is specified, we call all processes under the
4896                // give user id.
4897                if (packageName == null) {
4898                    if (app.userId != userId) {
4899                        continue;
4900                    }
4901                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4902                        continue;
4903                    }
4904                // Package has been specified, we want to hit all processes
4905                // that match it.  We need to qualify this by the processes
4906                // that are running under the specified app and user ID.
4907                } else {
4908                    if (UserHandle.getAppId(app.uid) != appId) {
4909                        continue;
4910                    }
4911                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4912                        continue;
4913                    }
4914                    if (!app.pkgList.containsKey(packageName)) {
4915                        continue;
4916                    }
4917                }
4918
4919                // Process has passed all conditions, kill it!
4920                if (!doit) {
4921                    return true;
4922                }
4923                app.removed = true;
4924                procs.add(app);
4925            }
4926        }
4927
4928        int N = procs.size();
4929        for (int i=0; i<N; i++) {
4930            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4931        }
4932        updateOomAdjLocked();
4933        return N > 0;
4934    }
4935
4936    private final boolean forceStopPackageLocked(String name, int appId,
4937            boolean callerWillRestart, boolean purgeCache, boolean doit,
4938            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4939        int i;
4940        int N;
4941
4942        if (userId == UserHandle.USER_ALL && name == null) {
4943            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4944        }
4945
4946        if (appId < 0 && name != null) {
4947            try {
4948                appId = UserHandle.getAppId(
4949                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4950            } catch (RemoteException e) {
4951            }
4952        }
4953
4954        if (doit) {
4955            if (name != null) {
4956                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4957                        + " user=" + userId + ": " + reason);
4958            } else {
4959                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4960            }
4961
4962            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4963            for (int ip=pmap.size()-1; ip>=0; ip--) {
4964                SparseArray<Long> ba = pmap.valueAt(ip);
4965                for (i=ba.size()-1; i>=0; i--) {
4966                    boolean remove = false;
4967                    final int entUid = ba.keyAt(i);
4968                    if (name != null) {
4969                        if (userId == UserHandle.USER_ALL) {
4970                            if (UserHandle.getAppId(entUid) == appId) {
4971                                remove = true;
4972                            }
4973                        } else {
4974                            if (entUid == UserHandle.getUid(userId, appId)) {
4975                                remove = true;
4976                            }
4977                        }
4978                    } else if (UserHandle.getUserId(entUid) == userId) {
4979                        remove = true;
4980                    }
4981                    if (remove) {
4982                        ba.removeAt(i);
4983                    }
4984                }
4985                if (ba.size() == 0) {
4986                    pmap.removeAt(ip);
4987                }
4988            }
4989        }
4990
4991        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4992                -100, callerWillRestart, true, doit, evenPersistent,
4993                name == null ? ("stop user " + userId) : ("stop " + name));
4994
4995        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4996            if (!doit) {
4997                return true;
4998            }
4999            didSomething = true;
5000        }
5001
5002        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5003            if (!doit) {
5004                return true;
5005            }
5006            didSomething = true;
5007        }
5008
5009        if (name == null) {
5010            // Remove all sticky broadcasts from this user.
5011            mStickyBroadcasts.remove(userId);
5012        }
5013
5014        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5015        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5016                userId, providers)) {
5017            if (!doit) {
5018                return true;
5019            }
5020            didSomething = true;
5021        }
5022        N = providers.size();
5023        for (i=0; i<N; i++) {
5024            removeDyingProviderLocked(null, providers.get(i), true);
5025        }
5026
5027        // Remove transient permissions granted from/to this package/user
5028        removeUriPermissionsForPackageLocked(name, userId, false);
5029
5030        if (name == null || uninstalling) {
5031            // Remove pending intents.  For now we only do this when force
5032            // stopping users, because we have some problems when doing this
5033            // for packages -- app widgets are not currently cleaned up for
5034            // such packages, so they can be left with bad pending intents.
5035            if (mIntentSenderRecords.size() > 0) {
5036                Iterator<WeakReference<PendingIntentRecord>> it
5037                        = mIntentSenderRecords.values().iterator();
5038                while (it.hasNext()) {
5039                    WeakReference<PendingIntentRecord> wpir = it.next();
5040                    if (wpir == null) {
5041                        it.remove();
5042                        continue;
5043                    }
5044                    PendingIntentRecord pir = wpir.get();
5045                    if (pir == null) {
5046                        it.remove();
5047                        continue;
5048                    }
5049                    if (name == null) {
5050                        // Stopping user, remove all objects for the user.
5051                        if (pir.key.userId != userId) {
5052                            // Not the same user, skip it.
5053                            continue;
5054                        }
5055                    } else {
5056                        if (UserHandle.getAppId(pir.uid) != appId) {
5057                            // Different app id, skip it.
5058                            continue;
5059                        }
5060                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5061                            // Different user, skip it.
5062                            continue;
5063                        }
5064                        if (!pir.key.packageName.equals(name)) {
5065                            // Different package, skip it.
5066                            continue;
5067                        }
5068                    }
5069                    if (!doit) {
5070                        return true;
5071                    }
5072                    didSomething = true;
5073                    it.remove();
5074                    pir.canceled = true;
5075                    if (pir.key.activity != null) {
5076                        pir.key.activity.pendingResults.remove(pir.ref);
5077                    }
5078                }
5079            }
5080        }
5081
5082        if (doit) {
5083            if (purgeCache && name != null) {
5084                AttributeCache ac = AttributeCache.instance();
5085                if (ac != null) {
5086                    ac.removePackage(name);
5087                }
5088            }
5089            if (mBooted) {
5090                mStackSupervisor.resumeTopActivitiesLocked();
5091                mStackSupervisor.scheduleIdleLocked();
5092            }
5093        }
5094
5095        return didSomething;
5096    }
5097
5098    private final boolean removeProcessLocked(ProcessRecord app,
5099            boolean callerWillRestart, boolean allowRestart, String reason) {
5100        final String name = app.processName;
5101        final int uid = app.uid;
5102        if (DEBUG_PROCESSES) Slog.d(
5103            TAG, "Force removing proc " + app.toShortString() + " (" + name
5104            + "/" + uid + ")");
5105
5106        mProcessNames.remove(name, uid);
5107        mIsolatedProcesses.remove(app.uid);
5108        if (mHeavyWeightProcess == app) {
5109            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5110                    mHeavyWeightProcess.userId, 0));
5111            mHeavyWeightProcess = null;
5112        }
5113        boolean needRestart = false;
5114        if (app.pid > 0 && app.pid != MY_PID) {
5115            int pid = app.pid;
5116            synchronized (mPidsSelfLocked) {
5117                mPidsSelfLocked.remove(pid);
5118                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5119            }
5120            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5121            if (app.isolated) {
5122                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5123            }
5124            killUnneededProcessLocked(app, reason);
5125            handleAppDiedLocked(app, true, allowRestart);
5126            removeLruProcessLocked(app);
5127
5128            if (app.persistent && !app.isolated) {
5129                if (!callerWillRestart) {
5130                    addAppLocked(app.info, false, null /* ABI override */);
5131                } else {
5132                    needRestart = true;
5133                }
5134            }
5135        } else {
5136            mRemovedProcesses.add(app);
5137        }
5138
5139        return needRestart;
5140    }
5141
5142    private final void processStartTimedOutLocked(ProcessRecord app) {
5143        final int pid = app.pid;
5144        boolean gone = false;
5145        synchronized (mPidsSelfLocked) {
5146            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5147            if (knownApp != null && knownApp.thread == null) {
5148                mPidsSelfLocked.remove(pid);
5149                gone = true;
5150            }
5151        }
5152
5153        if (gone) {
5154            Slog.w(TAG, "Process " + app + " failed to attach");
5155            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5156                    pid, app.uid, app.processName);
5157            mProcessNames.remove(app.processName, app.uid);
5158            mIsolatedProcesses.remove(app.uid);
5159            if (mHeavyWeightProcess == app) {
5160                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5161                        mHeavyWeightProcess.userId, 0));
5162                mHeavyWeightProcess = null;
5163            }
5164            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5165            if (app.isolated) {
5166                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5167            }
5168            // Take care of any launching providers waiting for this process.
5169            checkAppInLaunchingProvidersLocked(app, true);
5170            // Take care of any services that are waiting for the process.
5171            mServices.processStartTimedOutLocked(app);
5172            killUnneededProcessLocked(app, "start timeout");
5173            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5174                Slog.w(TAG, "Unattached app died before backup, skipping");
5175                try {
5176                    IBackupManager bm = IBackupManager.Stub.asInterface(
5177                            ServiceManager.getService(Context.BACKUP_SERVICE));
5178                    bm.agentDisconnected(app.info.packageName);
5179                } catch (RemoteException e) {
5180                    // Can't happen; the backup manager is local
5181                }
5182            }
5183            if (isPendingBroadcastProcessLocked(pid)) {
5184                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5185                skipPendingBroadcastLocked(pid);
5186            }
5187        } else {
5188            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5189        }
5190    }
5191
5192    private final boolean attachApplicationLocked(IApplicationThread thread,
5193            int pid) {
5194
5195        // Find the application record that is being attached...  either via
5196        // the pid if we are running in multiple processes, or just pull the
5197        // next app record if we are emulating process with anonymous threads.
5198        ProcessRecord app;
5199        if (pid != MY_PID && pid >= 0) {
5200            synchronized (mPidsSelfLocked) {
5201                app = mPidsSelfLocked.get(pid);
5202            }
5203        } else {
5204            app = null;
5205        }
5206
5207        if (app == null) {
5208            Slog.w(TAG, "No pending application record for pid " + pid
5209                    + " (IApplicationThread " + thread + "); dropping process");
5210            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5211            if (pid > 0 && pid != MY_PID) {
5212                Process.killProcessQuiet(pid);
5213            } else {
5214                try {
5215                    thread.scheduleExit();
5216                } catch (Exception e) {
5217                    // Ignore exceptions.
5218                }
5219            }
5220            return false;
5221        }
5222
5223        // If this application record is still attached to a previous
5224        // process, clean it up now.
5225        if (app.thread != null) {
5226            handleAppDiedLocked(app, true, true);
5227        }
5228
5229        // Tell the process all about itself.
5230
5231        if (localLOGV) Slog.v(
5232                TAG, "Binding process pid " + pid + " to record " + app);
5233
5234        final String processName = app.processName;
5235        try {
5236            AppDeathRecipient adr = new AppDeathRecipient(
5237                    app, pid, thread);
5238            thread.asBinder().linkToDeath(adr, 0);
5239            app.deathRecipient = adr;
5240        } catch (RemoteException e) {
5241            app.resetPackageList(mProcessStats);
5242            startProcessLocked(app, "link fail", processName, null /* ABI override */);
5243            return false;
5244        }
5245
5246        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5247
5248        app.makeActive(thread, mProcessStats);
5249        app.curAdj = app.setAdj = -100;
5250        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5251        app.forcingToForeground = null;
5252        updateProcessForegroundLocked(app, false, false);
5253        app.hasShownUi = false;
5254        app.debugging = false;
5255        app.cached = false;
5256
5257        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5258
5259        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5260        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5261
5262        if (!normalMode) {
5263            Slog.i(TAG, "Launching preboot mode app: " + app);
5264        }
5265
5266        if (localLOGV) Slog.v(
5267            TAG, "New app record " + app
5268            + " thread=" + thread.asBinder() + " pid=" + pid);
5269        try {
5270            int testMode = IApplicationThread.DEBUG_OFF;
5271            if (mDebugApp != null && mDebugApp.equals(processName)) {
5272                testMode = mWaitForDebugger
5273                    ? IApplicationThread.DEBUG_WAIT
5274                    : IApplicationThread.DEBUG_ON;
5275                app.debugging = true;
5276                if (mDebugTransient) {
5277                    mDebugApp = mOrigDebugApp;
5278                    mWaitForDebugger = mOrigWaitForDebugger;
5279                }
5280            }
5281            String profileFile = app.instrumentationProfileFile;
5282            ParcelFileDescriptor profileFd = null;
5283            boolean profileAutoStop = false;
5284            if (mProfileApp != null && mProfileApp.equals(processName)) {
5285                mProfileProc = app;
5286                profileFile = mProfileFile;
5287                profileFd = mProfileFd;
5288                profileAutoStop = mAutoStopProfiler;
5289            }
5290            boolean enableOpenGlTrace = false;
5291            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5292                enableOpenGlTrace = true;
5293                mOpenGlTraceApp = null;
5294            }
5295
5296            // If the app is being launched for restore or full backup, set it up specially
5297            boolean isRestrictedBackupMode = false;
5298            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5299                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5300                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5301                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5302            }
5303
5304            ensurePackageDexOpt(app.instrumentationInfo != null
5305                    ? app.instrumentationInfo.packageName
5306                    : app.info.packageName);
5307            if (app.instrumentationClass != null) {
5308                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5309            }
5310            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5311                    + processName + " with config " + mConfiguration);
5312            ApplicationInfo appInfo = app.instrumentationInfo != null
5313                    ? app.instrumentationInfo : app.info;
5314            app.compat = compatibilityInfoForPackageLocked(appInfo);
5315            if (profileFd != null) {
5316                profileFd = profileFd.dup();
5317            }
5318            thread.bindApplication(processName, appInfo, providers,
5319                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5320                    app.instrumentationArguments, app.instrumentationWatcher,
5321                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5322                    isRestrictedBackupMode || !normalMode, app.persistent,
5323                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5324                    mCoreSettingsObserver.getCoreSettingsLocked());
5325            updateLruProcessLocked(app, false, null);
5326            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5327        } catch (Exception e) {
5328            // todo: Yikes!  What should we do?  For now we will try to
5329            // start another process, but that could easily get us in
5330            // an infinite loop of restarting processes...
5331            Slog.w(TAG, "Exception thrown during bind!", e);
5332
5333            app.resetPackageList(mProcessStats);
5334            app.unlinkDeathRecipient();
5335            startProcessLocked(app, "bind fail", processName, null /* ABI override */);
5336            return false;
5337        }
5338
5339        // Remove this record from the list of starting applications.
5340        mPersistentStartingProcesses.remove(app);
5341        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5342                "Attach application locked removing on hold: " + app);
5343        mProcessesOnHold.remove(app);
5344
5345        boolean badApp = false;
5346        boolean didSomething = false;
5347
5348        // See if the top visible activity is waiting to run in this process...
5349        if (normalMode) {
5350            try {
5351                if (mStackSupervisor.attachApplicationLocked(app)) {
5352                    didSomething = true;
5353                }
5354            } catch (Exception e) {
5355                badApp = true;
5356            }
5357        }
5358
5359        // Find any services that should be running in this process...
5360        if (!badApp) {
5361            try {
5362                didSomething |= mServices.attachApplicationLocked(app, processName);
5363            } catch (Exception e) {
5364                badApp = true;
5365            }
5366        }
5367
5368        // Check if a next-broadcast receiver is in this process...
5369        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5370            try {
5371                didSomething |= sendPendingBroadcastsLocked(app);
5372            } catch (Exception e) {
5373                // If the app died trying to launch the receiver we declare it 'bad'
5374                badApp = true;
5375            }
5376        }
5377
5378        // Check whether the next backup agent is in this process...
5379        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5380            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5381            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5382            try {
5383                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5384                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5385                        mBackupTarget.backupMode);
5386            } catch (Exception e) {
5387                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5388                e.printStackTrace();
5389            }
5390        }
5391
5392        if (badApp) {
5393            // todo: Also need to kill application to deal with all
5394            // kinds of exceptions.
5395            handleAppDiedLocked(app, false, true);
5396            return false;
5397        }
5398
5399        if (!didSomething) {
5400            updateOomAdjLocked();
5401        }
5402
5403        return true;
5404    }
5405
5406    @Override
5407    public final void attachApplication(IApplicationThread thread) {
5408        synchronized (this) {
5409            int callingPid = Binder.getCallingPid();
5410            final long origId = Binder.clearCallingIdentity();
5411            attachApplicationLocked(thread, callingPid);
5412            Binder.restoreCallingIdentity(origId);
5413        }
5414    }
5415
5416    @Override
5417    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5418        final long origId = Binder.clearCallingIdentity();
5419        synchronized (this) {
5420            ActivityStack stack = ActivityRecord.getStackLocked(token);
5421            if (stack != null) {
5422                ActivityRecord r =
5423                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5424                if (stopProfiling) {
5425                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5426                        try {
5427                            mProfileFd.close();
5428                        } catch (IOException e) {
5429                        }
5430                        clearProfilerLocked();
5431                    }
5432                }
5433            }
5434        }
5435        Binder.restoreCallingIdentity(origId);
5436    }
5437
5438    void enableScreenAfterBoot() {
5439        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5440                SystemClock.uptimeMillis());
5441        mWindowManager.enableScreenAfterBoot();
5442
5443        synchronized (this) {
5444            updateEventDispatchingLocked();
5445        }
5446    }
5447
5448    @Override
5449    public void showBootMessage(final CharSequence msg, final boolean always) {
5450        enforceNotIsolatedCaller("showBootMessage");
5451        mWindowManager.showBootMessage(msg, always);
5452    }
5453
5454    @Override
5455    public void dismissKeyguardOnNextActivity() {
5456        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5457        final long token = Binder.clearCallingIdentity();
5458        try {
5459            synchronized (this) {
5460                if (DEBUG_LOCKSCREEN) logLockScreen("");
5461                if (mLockScreenShown) {
5462                    mLockScreenShown = false;
5463                    comeOutOfSleepIfNeededLocked();
5464                }
5465                mStackSupervisor.setDismissKeyguard(true);
5466            }
5467        } finally {
5468            Binder.restoreCallingIdentity(token);
5469        }
5470    }
5471
5472    final void finishBooting() {
5473        // Register receivers to handle package update events
5474        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5475
5476        synchronized (this) {
5477            // Ensure that any processes we had put on hold are now started
5478            // up.
5479            final int NP = mProcessesOnHold.size();
5480            if (NP > 0) {
5481                ArrayList<ProcessRecord> procs =
5482                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5483                for (int ip=0; ip<NP; ip++) {
5484                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5485                            + procs.get(ip));
5486                    startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */);
5487                }
5488            }
5489
5490            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5491                // Start looking for apps that are abusing wake locks.
5492                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5493                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5494                // Tell anyone interested that we are done booting!
5495                SystemProperties.set("sys.boot_completed", "1");
5496                SystemProperties.set("dev.bootcomplete", "1");
5497                for (int i=0; i<mStartedUsers.size(); i++) {
5498                    UserStartedState uss = mStartedUsers.valueAt(i);
5499                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5500                        uss.mState = UserStartedState.STATE_RUNNING;
5501                        final int userId = mStartedUsers.keyAt(i);
5502                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5503                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5504                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5505                        broadcastIntentLocked(null, null, intent, null,
5506                                new IIntentReceiver.Stub() {
5507                                    @Override
5508                                    public void performReceive(Intent intent, int resultCode,
5509                                            String data, Bundle extras, boolean ordered,
5510                                            boolean sticky, int sendingUser) {
5511                                        synchronized (ActivityManagerService.this) {
5512                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5513                                                    true, false);
5514                                        }
5515                                    }
5516                                },
5517                                0, null, null,
5518                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5519                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5520                                userId);
5521                    }
5522                }
5523                scheduleStartProfilesLocked();
5524            }
5525        }
5526    }
5527
5528    final void ensureBootCompleted() {
5529        boolean booting;
5530        boolean enableScreen;
5531        synchronized (this) {
5532            booting = mBooting;
5533            mBooting = false;
5534            enableScreen = !mBooted;
5535            mBooted = true;
5536        }
5537
5538        if (booting) {
5539            finishBooting();
5540        }
5541
5542        if (enableScreen) {
5543            enableScreenAfterBoot();
5544        }
5545    }
5546
5547    @Override
5548    public final void activityResumed(IBinder token) {
5549        final long origId = Binder.clearCallingIdentity();
5550        synchronized(this) {
5551            ActivityStack stack = ActivityRecord.getStackLocked(token);
5552            if (stack != null) {
5553                ActivityRecord.activityResumedLocked(token);
5554            }
5555        }
5556        Binder.restoreCallingIdentity(origId);
5557    }
5558
5559    @Override
5560    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5561        final long origId = Binder.clearCallingIdentity();
5562        synchronized(this) {
5563            ActivityStack stack = ActivityRecord.getStackLocked(token);
5564            if (stack != null) {
5565                stack.activityPausedLocked(token, false, persistentState);
5566            }
5567        }
5568        Binder.restoreCallingIdentity(origId);
5569    }
5570
5571    @Override
5572    public final void activityStopped(IBinder token, Bundle icicle,
5573            PersistableBundle persistentState, CharSequence description) {
5574        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5575
5576        // Refuse possible leaked file descriptors
5577        if (icicle != null && icicle.hasFileDescriptors()) {
5578            throw new IllegalArgumentException("File descriptors passed in Bundle");
5579        }
5580
5581        final long origId = Binder.clearCallingIdentity();
5582
5583        synchronized (this) {
5584            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5585            if (r != null) {
5586                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5587            }
5588        }
5589
5590        trimApplications();
5591
5592        Binder.restoreCallingIdentity(origId);
5593    }
5594
5595    @Override
5596    public final void activityDestroyed(IBinder token) {
5597        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5598        synchronized (this) {
5599            ActivityStack stack = ActivityRecord.getStackLocked(token);
5600            if (stack != null) {
5601                stack.activityDestroyedLocked(token);
5602            }
5603        }
5604    }
5605
5606    @Override
5607    public final void mediaResourcesReleased(IBinder token) {
5608        final long origId = Binder.clearCallingIdentity();
5609        try {
5610            synchronized (this) {
5611                ActivityStack stack = ActivityRecord.getStackLocked(token);
5612                if (stack != null) {
5613                    stack.mediaResourcesReleased(token);
5614                }
5615            }
5616        } finally {
5617            Binder.restoreCallingIdentity(origId);
5618        }
5619    }
5620
5621    @Override
5622    public String getCallingPackage(IBinder token) {
5623        synchronized (this) {
5624            ActivityRecord r = getCallingRecordLocked(token);
5625            return r != null ? r.info.packageName : null;
5626        }
5627    }
5628
5629    @Override
5630    public ComponentName getCallingActivity(IBinder token) {
5631        synchronized (this) {
5632            ActivityRecord r = getCallingRecordLocked(token);
5633            return r != null ? r.intent.getComponent() : null;
5634        }
5635    }
5636
5637    private ActivityRecord getCallingRecordLocked(IBinder token) {
5638        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5639        if (r == null) {
5640            return null;
5641        }
5642        return r.resultTo;
5643    }
5644
5645    @Override
5646    public ComponentName getActivityClassForToken(IBinder token) {
5647        synchronized(this) {
5648            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5649            if (r == null) {
5650                return null;
5651            }
5652            return r.intent.getComponent();
5653        }
5654    }
5655
5656    @Override
5657    public String getPackageForToken(IBinder token) {
5658        synchronized(this) {
5659            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5660            if (r == null) {
5661                return null;
5662            }
5663            return r.packageName;
5664        }
5665    }
5666
5667    @Override
5668    public IIntentSender getIntentSender(int type,
5669            String packageName, IBinder token, String resultWho,
5670            int requestCode, Intent[] intents, String[] resolvedTypes,
5671            int flags, Bundle options, int userId) {
5672        enforceNotIsolatedCaller("getIntentSender");
5673        // Refuse possible leaked file descriptors
5674        if (intents != null) {
5675            if (intents.length < 1) {
5676                throw new IllegalArgumentException("Intents array length must be >= 1");
5677            }
5678            for (int i=0; i<intents.length; i++) {
5679                Intent intent = intents[i];
5680                if (intent != null) {
5681                    if (intent.hasFileDescriptors()) {
5682                        throw new IllegalArgumentException("File descriptors passed in Intent");
5683                    }
5684                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5685                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5686                        throw new IllegalArgumentException(
5687                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5688                    }
5689                    intents[i] = new Intent(intent);
5690                }
5691            }
5692            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5693                throw new IllegalArgumentException(
5694                        "Intent array length does not match resolvedTypes length");
5695            }
5696        }
5697        if (options != null) {
5698            if (options.hasFileDescriptors()) {
5699                throw new IllegalArgumentException("File descriptors passed in options");
5700            }
5701        }
5702
5703        synchronized(this) {
5704            int callingUid = Binder.getCallingUid();
5705            int origUserId = userId;
5706            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5707                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5708                    "getIntentSender", null);
5709            if (origUserId == UserHandle.USER_CURRENT) {
5710                // We don't want to evaluate this until the pending intent is
5711                // actually executed.  However, we do want to always do the
5712                // security checking for it above.
5713                userId = UserHandle.USER_CURRENT;
5714            }
5715            try {
5716                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5717                    int uid = AppGlobals.getPackageManager()
5718                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5719                    if (!UserHandle.isSameApp(callingUid, uid)) {
5720                        String msg = "Permission Denial: getIntentSender() from pid="
5721                            + Binder.getCallingPid()
5722                            + ", uid=" + Binder.getCallingUid()
5723                            + ", (need uid=" + uid + ")"
5724                            + " is not allowed to send as package " + packageName;
5725                        Slog.w(TAG, msg);
5726                        throw new SecurityException(msg);
5727                    }
5728                }
5729
5730                return getIntentSenderLocked(type, packageName, callingUid, userId,
5731                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5732
5733            } catch (RemoteException e) {
5734                throw new SecurityException(e);
5735            }
5736        }
5737    }
5738
5739    IIntentSender getIntentSenderLocked(int type, String packageName,
5740            int callingUid, int userId, IBinder token, String resultWho,
5741            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5742            Bundle options) {
5743        if (DEBUG_MU)
5744            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5745        ActivityRecord activity = null;
5746        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5747            activity = ActivityRecord.isInStackLocked(token);
5748            if (activity == null) {
5749                return null;
5750            }
5751            if (activity.finishing) {
5752                return null;
5753            }
5754        }
5755
5756        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5757        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5758        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5759        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5760                |PendingIntent.FLAG_UPDATE_CURRENT);
5761
5762        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5763                type, packageName, activity, resultWho,
5764                requestCode, intents, resolvedTypes, flags, options, userId);
5765        WeakReference<PendingIntentRecord> ref;
5766        ref = mIntentSenderRecords.get(key);
5767        PendingIntentRecord rec = ref != null ? ref.get() : null;
5768        if (rec != null) {
5769            if (!cancelCurrent) {
5770                if (updateCurrent) {
5771                    if (rec.key.requestIntent != null) {
5772                        rec.key.requestIntent.replaceExtras(intents != null ?
5773                                intents[intents.length - 1] : null);
5774                    }
5775                    if (intents != null) {
5776                        intents[intents.length-1] = rec.key.requestIntent;
5777                        rec.key.allIntents = intents;
5778                        rec.key.allResolvedTypes = resolvedTypes;
5779                    } else {
5780                        rec.key.allIntents = null;
5781                        rec.key.allResolvedTypes = null;
5782                    }
5783                }
5784                return rec;
5785            }
5786            rec.canceled = true;
5787            mIntentSenderRecords.remove(key);
5788        }
5789        if (noCreate) {
5790            return rec;
5791        }
5792        rec = new PendingIntentRecord(this, key, callingUid);
5793        mIntentSenderRecords.put(key, rec.ref);
5794        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5795            if (activity.pendingResults == null) {
5796                activity.pendingResults
5797                        = new HashSet<WeakReference<PendingIntentRecord>>();
5798            }
5799            activity.pendingResults.add(rec.ref);
5800        }
5801        return rec;
5802    }
5803
5804    @Override
5805    public void cancelIntentSender(IIntentSender sender) {
5806        if (!(sender instanceof PendingIntentRecord)) {
5807            return;
5808        }
5809        synchronized(this) {
5810            PendingIntentRecord rec = (PendingIntentRecord)sender;
5811            try {
5812                int uid = AppGlobals.getPackageManager()
5813                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5814                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5815                    String msg = "Permission Denial: cancelIntentSender() from pid="
5816                        + Binder.getCallingPid()
5817                        + ", uid=" + Binder.getCallingUid()
5818                        + " is not allowed to cancel packges "
5819                        + rec.key.packageName;
5820                    Slog.w(TAG, msg);
5821                    throw new SecurityException(msg);
5822                }
5823            } catch (RemoteException e) {
5824                throw new SecurityException(e);
5825            }
5826            cancelIntentSenderLocked(rec, true);
5827        }
5828    }
5829
5830    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5831        rec.canceled = true;
5832        mIntentSenderRecords.remove(rec.key);
5833        if (cleanActivity && rec.key.activity != null) {
5834            rec.key.activity.pendingResults.remove(rec.ref);
5835        }
5836    }
5837
5838    @Override
5839    public String getPackageForIntentSender(IIntentSender pendingResult) {
5840        if (!(pendingResult instanceof PendingIntentRecord)) {
5841            return null;
5842        }
5843        try {
5844            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5845            return res.key.packageName;
5846        } catch (ClassCastException e) {
5847        }
5848        return null;
5849    }
5850
5851    @Override
5852    public int getUidForIntentSender(IIntentSender sender) {
5853        if (sender instanceof PendingIntentRecord) {
5854            try {
5855                PendingIntentRecord res = (PendingIntentRecord)sender;
5856                return res.uid;
5857            } catch (ClassCastException e) {
5858            }
5859        }
5860        return -1;
5861    }
5862
5863    @Override
5864    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5865        if (!(pendingResult instanceof PendingIntentRecord)) {
5866            return false;
5867        }
5868        try {
5869            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5870            if (res.key.allIntents == null) {
5871                return false;
5872            }
5873            for (int i=0; i<res.key.allIntents.length; i++) {
5874                Intent intent = res.key.allIntents[i];
5875                if (intent.getPackage() != null && intent.getComponent() != null) {
5876                    return false;
5877                }
5878            }
5879            return true;
5880        } catch (ClassCastException e) {
5881        }
5882        return false;
5883    }
5884
5885    @Override
5886    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5887        if (!(pendingResult instanceof PendingIntentRecord)) {
5888            return false;
5889        }
5890        try {
5891            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5892            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5893                return true;
5894            }
5895            return false;
5896        } catch (ClassCastException e) {
5897        }
5898        return false;
5899    }
5900
5901    @Override
5902    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5903        if (!(pendingResult instanceof PendingIntentRecord)) {
5904            return null;
5905        }
5906        try {
5907            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5908            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5909        } catch (ClassCastException e) {
5910        }
5911        return null;
5912    }
5913
5914    @Override
5915    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5916        if (!(pendingResult instanceof PendingIntentRecord)) {
5917            return null;
5918        }
5919        try {
5920            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5921            Intent intent = res.key.requestIntent;
5922            if (intent != null) {
5923                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5924                        || res.lastTagPrefix.equals(prefix))) {
5925                    return res.lastTag;
5926                }
5927                res.lastTagPrefix = prefix;
5928                StringBuilder sb = new StringBuilder(128);
5929                if (prefix != null) {
5930                    sb.append(prefix);
5931                }
5932                if (intent.getAction() != null) {
5933                    sb.append(intent.getAction());
5934                } else if (intent.getComponent() != null) {
5935                    intent.getComponent().appendShortString(sb);
5936                } else {
5937                    sb.append("?");
5938                }
5939                return res.lastTag = sb.toString();
5940            }
5941        } catch (ClassCastException e) {
5942        }
5943        return null;
5944    }
5945
5946    @Override
5947    public void setProcessLimit(int max) {
5948        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5949                "setProcessLimit()");
5950        synchronized (this) {
5951            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5952            mProcessLimitOverride = max;
5953        }
5954        trimApplications();
5955    }
5956
5957    @Override
5958    public int getProcessLimit() {
5959        synchronized (this) {
5960            return mProcessLimitOverride;
5961        }
5962    }
5963
5964    void foregroundTokenDied(ForegroundToken token) {
5965        synchronized (ActivityManagerService.this) {
5966            synchronized (mPidsSelfLocked) {
5967                ForegroundToken cur
5968                    = mForegroundProcesses.get(token.pid);
5969                if (cur != token) {
5970                    return;
5971                }
5972                mForegroundProcesses.remove(token.pid);
5973                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5974                if (pr == null) {
5975                    return;
5976                }
5977                pr.forcingToForeground = null;
5978                updateProcessForegroundLocked(pr, false, false);
5979            }
5980            updateOomAdjLocked();
5981        }
5982    }
5983
5984    @Override
5985    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5986        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5987                "setProcessForeground()");
5988        synchronized(this) {
5989            boolean changed = false;
5990
5991            synchronized (mPidsSelfLocked) {
5992                ProcessRecord pr = mPidsSelfLocked.get(pid);
5993                if (pr == null && isForeground) {
5994                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5995                    return;
5996                }
5997                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5998                if (oldToken != null) {
5999                    oldToken.token.unlinkToDeath(oldToken, 0);
6000                    mForegroundProcesses.remove(pid);
6001                    if (pr != null) {
6002                        pr.forcingToForeground = null;
6003                    }
6004                    changed = true;
6005                }
6006                if (isForeground && token != null) {
6007                    ForegroundToken newToken = new ForegroundToken() {
6008                        @Override
6009                        public void binderDied() {
6010                            foregroundTokenDied(this);
6011                        }
6012                    };
6013                    newToken.pid = pid;
6014                    newToken.token = token;
6015                    try {
6016                        token.linkToDeath(newToken, 0);
6017                        mForegroundProcesses.put(pid, newToken);
6018                        pr.forcingToForeground = token;
6019                        changed = true;
6020                    } catch (RemoteException e) {
6021                        // If the process died while doing this, we will later
6022                        // do the cleanup with the process death link.
6023                    }
6024                }
6025            }
6026
6027            if (changed) {
6028                updateOomAdjLocked();
6029            }
6030        }
6031    }
6032
6033    // =========================================================
6034    // PERMISSIONS
6035    // =========================================================
6036
6037    static class PermissionController extends IPermissionController.Stub {
6038        ActivityManagerService mActivityManagerService;
6039        PermissionController(ActivityManagerService activityManagerService) {
6040            mActivityManagerService = activityManagerService;
6041        }
6042
6043        @Override
6044        public boolean checkPermission(String permission, int pid, int uid) {
6045            return mActivityManagerService.checkPermission(permission, pid,
6046                    uid) == PackageManager.PERMISSION_GRANTED;
6047        }
6048    }
6049
6050    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6051        @Override
6052        public int checkComponentPermission(String permission, int pid, int uid,
6053                int owningUid, boolean exported) {
6054            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6055                    owningUid, exported);
6056        }
6057
6058        @Override
6059        public Object getAMSLock() {
6060            return ActivityManagerService.this;
6061        }
6062    }
6063
6064    /**
6065     * This can be called with or without the global lock held.
6066     */
6067    int checkComponentPermission(String permission, int pid, int uid,
6068            int owningUid, boolean exported) {
6069        // We might be performing an operation on behalf of an indirect binder
6070        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6071        // client identity accordingly before proceeding.
6072        Identity tlsIdentity = sCallerIdentity.get();
6073        if (tlsIdentity != null) {
6074            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6075                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6076            uid = tlsIdentity.uid;
6077            pid = tlsIdentity.pid;
6078        }
6079
6080        if (pid == MY_PID) {
6081            return PackageManager.PERMISSION_GRANTED;
6082        }
6083
6084        return ActivityManager.checkComponentPermission(permission, uid,
6085                owningUid, exported);
6086    }
6087
6088    /**
6089     * As the only public entry point for permissions checking, this method
6090     * can enforce the semantic that requesting a check on a null global
6091     * permission is automatically denied.  (Internally a null permission
6092     * string is used when calling {@link #checkComponentPermission} in cases
6093     * when only uid-based security is needed.)
6094     *
6095     * This can be called with or without the global lock held.
6096     */
6097    @Override
6098    public int checkPermission(String permission, int pid, int uid) {
6099        if (permission == null) {
6100            return PackageManager.PERMISSION_DENIED;
6101        }
6102        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6103    }
6104
6105    /**
6106     * Binder IPC calls go through the public entry point.
6107     * This can be called with or without the global lock held.
6108     */
6109    int checkCallingPermission(String permission) {
6110        return checkPermission(permission,
6111                Binder.getCallingPid(),
6112                UserHandle.getAppId(Binder.getCallingUid()));
6113    }
6114
6115    /**
6116     * This can be called with or without the global lock held.
6117     */
6118    void enforceCallingPermission(String permission, String func) {
6119        if (checkCallingPermission(permission)
6120                == PackageManager.PERMISSION_GRANTED) {
6121            return;
6122        }
6123
6124        String msg = "Permission Denial: " + func + " from pid="
6125                + Binder.getCallingPid()
6126                + ", uid=" + Binder.getCallingUid()
6127                + " requires " + permission;
6128        Slog.w(TAG, msg);
6129        throw new SecurityException(msg);
6130    }
6131
6132    /**
6133     * Determine if UID is holding permissions required to access {@link Uri} in
6134     * the given {@link ProviderInfo}. Final permission checking is always done
6135     * in {@link ContentProvider}.
6136     */
6137    private final boolean checkHoldingPermissionsLocked(
6138            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6139        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6140                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6141        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6142            return false;
6143        }
6144        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6145    }
6146
6147    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6148            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6149        if (pi.applicationInfo.uid == uid) {
6150            return true;
6151        } else if (!pi.exported) {
6152            return false;
6153        }
6154
6155        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6156        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6157        try {
6158            // check if target holds top-level <provider> permissions
6159            if (!readMet && pi.readPermission != null && considerUidPermissions
6160                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6161                readMet = true;
6162            }
6163            if (!writeMet && pi.writePermission != null && considerUidPermissions
6164                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6165                writeMet = true;
6166            }
6167
6168            // track if unprotected read/write is allowed; any denied
6169            // <path-permission> below removes this ability
6170            boolean allowDefaultRead = pi.readPermission == null;
6171            boolean allowDefaultWrite = pi.writePermission == null;
6172
6173            // check if target holds any <path-permission> that match uri
6174            final PathPermission[] pps = pi.pathPermissions;
6175            if (pps != null) {
6176                final String path = grantUri.uri.getPath();
6177                int i = pps.length;
6178                while (i > 0 && (!readMet || !writeMet)) {
6179                    i--;
6180                    PathPermission pp = pps[i];
6181                    if (pp.match(path)) {
6182                        if (!readMet) {
6183                            final String pprperm = pp.getReadPermission();
6184                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6185                                    + pprperm + " for " + pp.getPath()
6186                                    + ": match=" + pp.match(path)
6187                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6188                            if (pprperm != null) {
6189                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6190                                        == PERMISSION_GRANTED) {
6191                                    readMet = true;
6192                                } else {
6193                                    allowDefaultRead = false;
6194                                }
6195                            }
6196                        }
6197                        if (!writeMet) {
6198                            final String ppwperm = pp.getWritePermission();
6199                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6200                                    + ppwperm + " for " + pp.getPath()
6201                                    + ": match=" + pp.match(path)
6202                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6203                            if (ppwperm != null) {
6204                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6205                                        == PERMISSION_GRANTED) {
6206                                    writeMet = true;
6207                                } else {
6208                                    allowDefaultWrite = false;
6209                                }
6210                            }
6211                        }
6212                    }
6213                }
6214            }
6215
6216            // grant unprotected <provider> read/write, if not blocked by
6217            // <path-permission> above
6218            if (allowDefaultRead) readMet = true;
6219            if (allowDefaultWrite) writeMet = true;
6220
6221        } catch (RemoteException e) {
6222            return false;
6223        }
6224
6225        return readMet && writeMet;
6226    }
6227
6228    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6229        ProviderInfo pi = null;
6230        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6231        if (cpr != null) {
6232            pi = cpr.info;
6233        } else {
6234            try {
6235                pi = AppGlobals.getPackageManager().resolveContentProvider(
6236                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6237            } catch (RemoteException ex) {
6238            }
6239        }
6240        return pi;
6241    }
6242
6243    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6244        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6245        if (targetUris != null) {
6246            return targetUris.get(grantUri);
6247        }
6248        return null;
6249    }
6250
6251    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6252            String targetPkg, int targetUid, GrantUri grantUri) {
6253        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6254        if (targetUris == null) {
6255            targetUris = Maps.newArrayMap();
6256            mGrantedUriPermissions.put(targetUid, targetUris);
6257        }
6258
6259        UriPermission perm = targetUris.get(grantUri);
6260        if (perm == null) {
6261            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6262            targetUris.put(grantUri, perm);
6263        }
6264
6265        return perm;
6266    }
6267
6268    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6269            final int modeFlags) {
6270        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6271        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6272                : UriPermission.STRENGTH_OWNED;
6273
6274        // Root gets to do everything.
6275        if (uid == 0) {
6276            return true;
6277        }
6278
6279        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6280        if (perms == null) return false;
6281
6282        // First look for exact match
6283        final UriPermission exactPerm = perms.get(grantUri);
6284        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6285            return true;
6286        }
6287
6288        // No exact match, look for prefixes
6289        final int N = perms.size();
6290        for (int i = 0; i < N; i++) {
6291            final UriPermission perm = perms.valueAt(i);
6292            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6293                    && perm.getStrength(modeFlags) >= minStrength) {
6294                return true;
6295            }
6296        }
6297
6298        return false;
6299    }
6300
6301    @Override
6302    public int checkUriPermission(Uri uri, int pid, int uid,
6303            final int modeFlags, int userId) {
6304        enforceNotIsolatedCaller("checkUriPermission");
6305
6306        // Another redirected-binder-call permissions check as in
6307        // {@link checkComponentPermission}.
6308        Identity tlsIdentity = sCallerIdentity.get();
6309        if (tlsIdentity != null) {
6310            uid = tlsIdentity.uid;
6311            pid = tlsIdentity.pid;
6312        }
6313
6314        // Our own process gets to do everything.
6315        if (pid == MY_PID) {
6316            return PackageManager.PERMISSION_GRANTED;
6317        }
6318        synchronized (this) {
6319            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6320                    ? PackageManager.PERMISSION_GRANTED
6321                    : PackageManager.PERMISSION_DENIED;
6322        }
6323    }
6324
6325    /**
6326     * Check if the targetPkg can be granted permission to access uri by
6327     * the callingUid using the given modeFlags.  Throws a security exception
6328     * if callingUid is not allowed to do this.  Returns the uid of the target
6329     * if the URI permission grant should be performed; returns -1 if it is not
6330     * needed (for example targetPkg already has permission to access the URI).
6331     * If you already know the uid of the target, you can supply it in
6332     * lastTargetUid else set that to -1.
6333     */
6334    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6335            final int modeFlags, int lastTargetUid) {
6336        if (!Intent.isAccessUriMode(modeFlags)) {
6337            return -1;
6338        }
6339
6340        if (targetPkg != null) {
6341            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6342                    "Checking grant " + targetPkg + " permission to " + grantUri);
6343        }
6344
6345        final IPackageManager pm = AppGlobals.getPackageManager();
6346
6347        // If this is not a content: uri, we can't do anything with it.
6348        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6349            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6350                    "Can't grant URI permission for non-content URI: " + grantUri);
6351            return -1;
6352        }
6353
6354        final String authority = grantUri.uri.getAuthority();
6355        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6356        if (pi == null) {
6357            Slog.w(TAG, "No content provider found for permission check: " +
6358                    grantUri.uri.toSafeString());
6359            return -1;
6360        }
6361
6362        int targetUid = lastTargetUid;
6363        if (targetUid < 0 && targetPkg != null) {
6364            try {
6365                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6366                if (targetUid < 0) {
6367                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6368                            "Can't grant URI permission no uid for: " + targetPkg);
6369                    return -1;
6370                }
6371            } catch (RemoteException ex) {
6372                return -1;
6373            }
6374        }
6375
6376        if (targetUid >= 0) {
6377            // First...  does the target actually need this permission?
6378            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6379                // No need to grant the target this permission.
6380                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6381                        "Target " + targetPkg + " already has full permission to " + grantUri);
6382                return -1;
6383            }
6384        } else {
6385            // First...  there is no target package, so can anyone access it?
6386            boolean allowed = pi.exported;
6387            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6388                if (pi.readPermission != null) {
6389                    allowed = false;
6390                }
6391            }
6392            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6393                if (pi.writePermission != null) {
6394                    allowed = false;
6395                }
6396            }
6397            if (allowed) {
6398                return -1;
6399            }
6400        }
6401
6402        /* There is a special cross user grant if:
6403         * - The target is on another user.
6404         * - Apps on the current user can access the uri without any uid permissions.
6405         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6406         * grant uri permissions.
6407         */
6408        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6409                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6410                modeFlags, false /*without considering the uid permissions*/);
6411
6412        // Second...  is the provider allowing granting of URI permissions?
6413        if (!specialCrossUserGrant) {
6414            if (!pi.grantUriPermissions) {
6415                throw new SecurityException("Provider " + pi.packageName
6416                        + "/" + pi.name
6417                        + " does not allow granting of Uri permissions (uri "
6418                        + grantUri + ")");
6419            }
6420            if (pi.uriPermissionPatterns != null) {
6421                final int N = pi.uriPermissionPatterns.length;
6422                boolean allowed = false;
6423                for (int i=0; i<N; i++) {
6424                    if (pi.uriPermissionPatterns[i] != null
6425                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6426                        allowed = true;
6427                        break;
6428                    }
6429                }
6430                if (!allowed) {
6431                    throw new SecurityException("Provider " + pi.packageName
6432                            + "/" + pi.name
6433                            + " does not allow granting of permission to path of Uri "
6434                            + grantUri);
6435                }
6436            }
6437        }
6438
6439        // Third...  does the caller itself have permission to access
6440        // this uri?
6441        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6442            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6443                // Require they hold a strong enough Uri permission
6444                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6445                    throw new SecurityException("Uid " + callingUid
6446                            + " does not have permission to uri " + grantUri);
6447                }
6448            }
6449        }
6450        return targetUid;
6451    }
6452
6453    @Override
6454    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6455            final int modeFlags, int userId) {
6456        enforceNotIsolatedCaller("checkGrantUriPermission");
6457        synchronized(this) {
6458            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6459                    new GrantUri(userId, uri, false), modeFlags, -1);
6460        }
6461    }
6462
6463    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6464            final int modeFlags, UriPermissionOwner owner) {
6465        if (!Intent.isAccessUriMode(modeFlags)) {
6466            return;
6467        }
6468
6469        // So here we are: the caller has the assumed permission
6470        // to the uri, and the target doesn't.  Let's now give this to
6471        // the target.
6472
6473        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6474                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6475
6476        final String authority = grantUri.uri.getAuthority();
6477        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6478        if (pi == null) {
6479            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6480            return;
6481        }
6482
6483        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6484            grantUri.prefix = true;
6485        }
6486        final UriPermission perm = findOrCreateUriPermissionLocked(
6487                pi.packageName, targetPkg, targetUid, grantUri);
6488        perm.grantModes(modeFlags, owner);
6489    }
6490
6491    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6492            final int modeFlags, UriPermissionOwner owner) {
6493        if (targetPkg == null) {
6494            throw new NullPointerException("targetPkg");
6495        }
6496
6497        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6498                -1);
6499        if (targetUid < 0) {
6500            return;
6501        }
6502
6503        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6504                owner);
6505    }
6506
6507    static class NeededUriGrants extends ArrayList<GrantUri> {
6508        final String targetPkg;
6509        final int targetUid;
6510        final int flags;
6511
6512        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6513            this.targetPkg = targetPkg;
6514            this.targetUid = targetUid;
6515            this.flags = flags;
6516        }
6517    }
6518
6519    /**
6520     * Like checkGrantUriPermissionLocked, but takes an Intent.
6521     */
6522    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6523            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6524        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6525                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6526                + " clip=" + (intent != null ? intent.getClipData() : null)
6527                + " from " + intent + "; flags=0x"
6528                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6529
6530        if (targetPkg == null) {
6531            throw new NullPointerException("targetPkg");
6532        }
6533
6534        if (intent == null) {
6535            return null;
6536        }
6537        Uri data = intent.getData();
6538        ClipData clip = intent.getClipData();
6539        if (data == null && clip == null) {
6540            return null;
6541        }
6542        final IPackageManager pm = AppGlobals.getPackageManager();
6543        int targetUid;
6544        if (needed != null) {
6545            targetUid = needed.targetUid;
6546        } else {
6547            try {
6548                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6549            } catch (RemoteException ex) {
6550                return null;
6551            }
6552            if (targetUid < 0) {
6553                if (DEBUG_URI_PERMISSION) {
6554                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6555                            + " on user " + targetUserId);
6556                }
6557                return null;
6558            }
6559        }
6560        if (data != null) {
6561            GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data);
6562            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6563                    targetUid);
6564            if (targetUid > 0) {
6565                if (needed == null) {
6566                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6567                }
6568                needed.add(grantUri);
6569            }
6570        }
6571        if (clip != null) {
6572            for (int i=0; i<clip.getItemCount(); i++) {
6573                Uri uri = clip.getItemAt(i).getUri();
6574                if (uri != null) {
6575                    GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri);
6576                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6577                            targetUid);
6578                    if (targetUid > 0) {
6579                        if (needed == null) {
6580                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6581                        }
6582                        needed.add(grantUri);
6583                    }
6584                } else {
6585                    Intent clipIntent = clip.getItemAt(i).getIntent();
6586                    if (clipIntent != null) {
6587                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6588                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6589                        if (newNeeded != null) {
6590                            needed = newNeeded;
6591                        }
6592                    }
6593                }
6594            }
6595        }
6596
6597        return needed;
6598    }
6599
6600    /**
6601     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6602     */
6603    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6604            UriPermissionOwner owner) {
6605        if (needed != null) {
6606            for (int i=0; i<needed.size(); i++) {
6607                GrantUri grantUri = needed.get(i);
6608                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6609                        grantUri, needed.flags, owner);
6610            }
6611        }
6612    }
6613
6614    void grantUriPermissionFromIntentLocked(int callingUid,
6615            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6616        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6617                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6618        if (needed == null) {
6619            return;
6620        }
6621
6622        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6623    }
6624
6625    @Override
6626    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6627            final int modeFlags, int userId) {
6628        enforceNotIsolatedCaller("grantUriPermission");
6629        GrantUri grantUri = new GrantUri(userId, uri, false);
6630        synchronized(this) {
6631            final ProcessRecord r = getRecordForAppLocked(caller);
6632            if (r == null) {
6633                throw new SecurityException("Unable to find app for caller "
6634                        + caller
6635                        + " when granting permission to uri " + grantUri);
6636            }
6637            if (targetPkg == null) {
6638                throw new IllegalArgumentException("null target");
6639            }
6640            if (grantUri == null) {
6641                throw new IllegalArgumentException("null uri");
6642            }
6643
6644            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6645                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6646                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6647                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6648
6649            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null);
6650        }
6651    }
6652
6653    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6654        if (perm.modeFlags == 0) {
6655            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6656                    perm.targetUid);
6657            if (perms != null) {
6658                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6659                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6660
6661                perms.remove(perm.uri);
6662                if (perms.isEmpty()) {
6663                    mGrantedUriPermissions.remove(perm.targetUid);
6664                }
6665            }
6666        }
6667    }
6668
6669    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6670        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6671
6672        final IPackageManager pm = AppGlobals.getPackageManager();
6673        final String authority = grantUri.uri.getAuthority();
6674        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6675        if (pi == null) {
6676            Slog.w(TAG, "No content provider found for permission revoke: "
6677                    + grantUri.toSafeString());
6678            return;
6679        }
6680
6681        // Does the caller have this permission on the URI?
6682        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6683            // Right now, if you are not the original owner of the permission,
6684            // you are not allowed to revoke it.
6685            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6686                throw new SecurityException("Uid " + callingUid
6687                        + " does not have permission to uri " + grantUri);
6688            //}
6689        }
6690
6691        boolean persistChanged = false;
6692
6693        // Go through all of the permissions and remove any that match.
6694        int N = mGrantedUriPermissions.size();
6695        for (int i = 0; i < N; i++) {
6696            final int targetUid = mGrantedUriPermissions.keyAt(i);
6697            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6698
6699            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6700                final UriPermission perm = it.next();
6701                if (perm.uri.sourceUserId == grantUri.sourceUserId
6702                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6703                    if (DEBUG_URI_PERMISSION)
6704                        Slog.v(TAG,
6705                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6706                    persistChanged |= perm.revokeModes(
6707                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6708                    if (perm.modeFlags == 0) {
6709                        it.remove();
6710                    }
6711                }
6712            }
6713
6714            if (perms.isEmpty()) {
6715                mGrantedUriPermissions.remove(targetUid);
6716                N--;
6717                i--;
6718            }
6719        }
6720
6721        if (persistChanged) {
6722            schedulePersistUriGrants();
6723        }
6724    }
6725
6726    @Override
6727    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6728            int userId) {
6729        enforceNotIsolatedCaller("revokeUriPermission");
6730        synchronized(this) {
6731            final ProcessRecord r = getRecordForAppLocked(caller);
6732            if (r == null) {
6733                throw new SecurityException("Unable to find app for caller "
6734                        + caller
6735                        + " when revoking permission to uri " + uri);
6736            }
6737            if (uri == null) {
6738                Slog.w(TAG, "revokeUriPermission: null uri");
6739                return;
6740            }
6741
6742            if (!Intent.isAccessUriMode(modeFlags)) {
6743                return;
6744            }
6745
6746            final IPackageManager pm = AppGlobals.getPackageManager();
6747            final String authority = uri.getAuthority();
6748            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6749            if (pi == null) {
6750                Slog.w(TAG, "No content provider found for permission revoke: "
6751                        + uri.toSafeString());
6752                return;
6753            }
6754
6755            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6756        }
6757    }
6758
6759    /**
6760     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6761     * given package.
6762     *
6763     * @param packageName Package name to match, or {@code null} to apply to all
6764     *            packages.
6765     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6766     *            to all users.
6767     * @param persistable If persistable grants should be removed.
6768     */
6769    private void removeUriPermissionsForPackageLocked(
6770            String packageName, int userHandle, boolean persistable) {
6771        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6772            throw new IllegalArgumentException("Must narrow by either package or user");
6773        }
6774
6775        boolean persistChanged = false;
6776
6777        int N = mGrantedUriPermissions.size();
6778        for (int i = 0; i < N; i++) {
6779            final int targetUid = mGrantedUriPermissions.keyAt(i);
6780            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6781
6782            // Only inspect grants matching user
6783            if (userHandle == UserHandle.USER_ALL
6784                    || userHandle == UserHandle.getUserId(targetUid)) {
6785                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6786                    final UriPermission perm = it.next();
6787
6788                    // Only inspect grants matching package
6789                    if (packageName == null || perm.sourcePkg.equals(packageName)
6790                            || perm.targetPkg.equals(packageName)) {
6791                        persistChanged |= perm.revokeModes(
6792                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6793
6794                        // Only remove when no modes remain; any persisted grants
6795                        // will keep this alive.
6796                        if (perm.modeFlags == 0) {
6797                            it.remove();
6798                        }
6799                    }
6800                }
6801
6802                if (perms.isEmpty()) {
6803                    mGrantedUriPermissions.remove(targetUid);
6804                    N--;
6805                    i--;
6806                }
6807            }
6808        }
6809
6810        if (persistChanged) {
6811            schedulePersistUriGrants();
6812        }
6813    }
6814
6815    @Override
6816    public IBinder newUriPermissionOwner(String name) {
6817        enforceNotIsolatedCaller("newUriPermissionOwner");
6818        synchronized(this) {
6819            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6820            return owner.getExternalTokenLocked();
6821        }
6822    }
6823
6824    @Override
6825    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6826            final int modeFlags, int userId) {
6827        synchronized(this) {
6828            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6829            if (owner == null) {
6830                throw new IllegalArgumentException("Unknown owner: " + token);
6831            }
6832            if (fromUid != Binder.getCallingUid()) {
6833                if (Binder.getCallingUid() != Process.myUid()) {
6834                    // Only system code can grant URI permissions on behalf
6835                    // of other users.
6836                    throw new SecurityException("nice try");
6837                }
6838            }
6839            if (targetPkg == null) {
6840                throw new IllegalArgumentException("null target");
6841            }
6842            if (uri == null) {
6843                throw new IllegalArgumentException("null uri");
6844            }
6845
6846            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false),
6847                    modeFlags, owner);
6848        }
6849    }
6850
6851    @Override
6852    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6853        synchronized(this) {
6854            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6855            if (owner == null) {
6856                throw new IllegalArgumentException("Unknown owner: " + token);
6857            }
6858
6859            if (uri == null) {
6860                owner.removeUriPermissionsLocked(mode);
6861            } else {
6862                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
6863            }
6864        }
6865    }
6866
6867    private void schedulePersistUriGrants() {
6868        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6869            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6870                    10 * DateUtils.SECOND_IN_MILLIS);
6871        }
6872    }
6873
6874    private void writeGrantedUriPermissions() {
6875        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6876
6877        // Snapshot permissions so we can persist without lock
6878        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6879        synchronized (this) {
6880            final int size = mGrantedUriPermissions.size();
6881            for (int i = 0; i < size; i++) {
6882                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6883                for (UriPermission perm : perms.values()) {
6884                    if (perm.persistedModeFlags != 0) {
6885                        persist.add(perm.snapshot());
6886                    }
6887                }
6888            }
6889        }
6890
6891        FileOutputStream fos = null;
6892        try {
6893            fos = mGrantFile.startWrite();
6894
6895            XmlSerializer out = new FastXmlSerializer();
6896            out.setOutput(fos, "utf-8");
6897            out.startDocument(null, true);
6898            out.startTag(null, TAG_URI_GRANTS);
6899            for (UriPermission.Snapshot perm : persist) {
6900                out.startTag(null, TAG_URI_GRANT);
6901                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
6902                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
6903                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6904                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6905                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6906                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6907                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6908                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6909                out.endTag(null, TAG_URI_GRANT);
6910            }
6911            out.endTag(null, TAG_URI_GRANTS);
6912            out.endDocument();
6913
6914            mGrantFile.finishWrite(fos);
6915        } catch (IOException e) {
6916            if (fos != null) {
6917                mGrantFile.failWrite(fos);
6918            }
6919        }
6920    }
6921
6922    private void readGrantedUriPermissionsLocked() {
6923        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6924
6925        final long now = System.currentTimeMillis();
6926
6927        FileInputStream fis = null;
6928        try {
6929            fis = mGrantFile.openRead();
6930            final XmlPullParser in = Xml.newPullParser();
6931            in.setInput(fis, null);
6932
6933            int type;
6934            while ((type = in.next()) != END_DOCUMENT) {
6935                final String tag = in.getName();
6936                if (type == START_TAG) {
6937                    if (TAG_URI_GRANT.equals(tag)) {
6938                        final int sourceUserId;
6939                        final int targetUserId;
6940                        final int userHandle = readIntAttribute(in,
6941                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
6942                        if (userHandle != UserHandle.USER_NULL) {
6943                            // For backwards compatibility.
6944                            sourceUserId = userHandle;
6945                            targetUserId = userHandle;
6946                        } else {
6947                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
6948                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
6949                        }
6950                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6951                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6952                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6953                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
6954                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6955                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6956
6957                        // Sanity check that provider still belongs to source package
6958                        final ProviderInfo pi = getProviderInfoLocked(
6959                                uri.getAuthority(), sourceUserId);
6960                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6961                            int targetUid = -1;
6962                            try {
6963                                targetUid = AppGlobals.getPackageManager()
6964                                        .getPackageUid(targetPkg, targetUserId);
6965                            } catch (RemoteException e) {
6966                            }
6967                            if (targetUid != -1) {
6968                                final UriPermission perm = findOrCreateUriPermissionLocked(
6969                                        sourcePkg, targetPkg, targetUid,
6970                                        new GrantUri(sourceUserId, uri, prefix));
6971                                perm.initPersistedModes(modeFlags, createdTime);
6972                            }
6973                        } else {
6974                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6975                                    + " but instead found " + pi);
6976                        }
6977                    }
6978                }
6979            }
6980        } catch (FileNotFoundException e) {
6981            // Missing grants is okay
6982        } catch (IOException e) {
6983            Log.wtf(TAG, "Failed reading Uri grants", e);
6984        } catch (XmlPullParserException e) {
6985            Log.wtf(TAG, "Failed reading Uri grants", e);
6986        } finally {
6987            IoUtils.closeQuietly(fis);
6988        }
6989    }
6990
6991    @Override
6992    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6993        enforceNotIsolatedCaller("takePersistableUriPermission");
6994
6995        Preconditions.checkFlagsArgument(modeFlags,
6996                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6997
6998        synchronized (this) {
6999            final int callingUid = Binder.getCallingUid();
7000            boolean persistChanged = false;
7001            GrantUri grantUri = new GrantUri(userId, uri, false);
7002
7003            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7004                    new GrantUri(userId, uri, false));
7005            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7006                    new GrantUri(userId, uri, true));
7007
7008            final boolean exactValid = (exactPerm != null)
7009                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7010            final boolean prefixValid = (prefixPerm != null)
7011                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7012
7013            if (!(exactValid || prefixValid)) {
7014                throw new SecurityException("No persistable permission grants found for UID "
7015                        + callingUid + " and Uri " + grantUri.toSafeString());
7016            }
7017
7018            if (exactValid) {
7019                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7020            }
7021            if (prefixValid) {
7022                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7023            }
7024
7025            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7026
7027            if (persistChanged) {
7028                schedulePersistUriGrants();
7029            }
7030        }
7031    }
7032
7033    @Override
7034    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7035        enforceNotIsolatedCaller("releasePersistableUriPermission");
7036
7037        Preconditions.checkFlagsArgument(modeFlags,
7038                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7039
7040        synchronized (this) {
7041            final int callingUid = Binder.getCallingUid();
7042            boolean persistChanged = false;
7043
7044            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7045                    new GrantUri(userId, uri, false));
7046            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7047                    new GrantUri(userId, uri, true));
7048            if (exactPerm == null && prefixPerm == null) {
7049                throw new SecurityException("No permission grants found for UID " + callingUid
7050                        + " and Uri " + uri.toSafeString());
7051            }
7052
7053            if (exactPerm != null) {
7054                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7055                removeUriPermissionIfNeededLocked(exactPerm);
7056            }
7057            if (prefixPerm != null) {
7058                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7059                removeUriPermissionIfNeededLocked(prefixPerm);
7060            }
7061
7062            if (persistChanged) {
7063                schedulePersistUriGrants();
7064            }
7065        }
7066    }
7067
7068    /**
7069     * Prune any older {@link UriPermission} for the given UID until outstanding
7070     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7071     *
7072     * @return if any mutations occured that require persisting.
7073     */
7074    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7075        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7076        if (perms == null) return false;
7077        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7078
7079        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7080        for (UriPermission perm : perms.values()) {
7081            if (perm.persistedModeFlags != 0) {
7082                persisted.add(perm);
7083            }
7084        }
7085
7086        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7087        if (trimCount <= 0) return false;
7088
7089        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7090        for (int i = 0; i < trimCount; i++) {
7091            final UriPermission perm = persisted.get(i);
7092
7093            if (DEBUG_URI_PERMISSION) {
7094                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7095            }
7096
7097            perm.releasePersistableModes(~0);
7098            removeUriPermissionIfNeededLocked(perm);
7099        }
7100
7101        return true;
7102    }
7103
7104    @Override
7105    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7106            String packageName, boolean incoming) {
7107        enforceNotIsolatedCaller("getPersistedUriPermissions");
7108        Preconditions.checkNotNull(packageName, "packageName");
7109
7110        final int callingUid = Binder.getCallingUid();
7111        final IPackageManager pm = AppGlobals.getPackageManager();
7112        try {
7113            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7114            if (packageUid != callingUid) {
7115                throw new SecurityException(
7116                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7117            }
7118        } catch (RemoteException e) {
7119            throw new SecurityException("Failed to verify package name ownership");
7120        }
7121
7122        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7123        synchronized (this) {
7124            if (incoming) {
7125                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7126                        callingUid);
7127                if (perms == null) {
7128                    Slog.w(TAG, "No permission grants found for " + packageName);
7129                } else {
7130                    for (UriPermission perm : perms.values()) {
7131                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7132                            result.add(perm.buildPersistedPublicApiObject());
7133                        }
7134                    }
7135                }
7136            } else {
7137                final int size = mGrantedUriPermissions.size();
7138                for (int i = 0; i < size; i++) {
7139                    final ArrayMap<GrantUri, UriPermission> perms =
7140                            mGrantedUriPermissions.valueAt(i);
7141                    for (UriPermission perm : perms.values()) {
7142                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7143                            result.add(perm.buildPersistedPublicApiObject());
7144                        }
7145                    }
7146                }
7147            }
7148        }
7149        return new ParceledListSlice<android.content.UriPermission>(result);
7150    }
7151
7152    @Override
7153    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7154        synchronized (this) {
7155            ProcessRecord app =
7156                who != null ? getRecordForAppLocked(who) : null;
7157            if (app == null) return;
7158
7159            Message msg = Message.obtain();
7160            msg.what = WAIT_FOR_DEBUGGER_MSG;
7161            msg.obj = app;
7162            msg.arg1 = waiting ? 1 : 0;
7163            mHandler.sendMessage(msg);
7164        }
7165    }
7166
7167    @Override
7168    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7169        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7170        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7171        outInfo.availMem = Process.getFreeMemory();
7172        outInfo.totalMem = Process.getTotalMemory();
7173        outInfo.threshold = homeAppMem;
7174        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7175        outInfo.hiddenAppThreshold = cachedAppMem;
7176        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7177                ProcessList.SERVICE_ADJ);
7178        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7179                ProcessList.VISIBLE_APP_ADJ);
7180        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7181                ProcessList.FOREGROUND_APP_ADJ);
7182    }
7183
7184    // =========================================================
7185    // TASK MANAGEMENT
7186    // =========================================================
7187
7188    @Override
7189    public List<IAppTask> getAppTasks() {
7190        final PackageManager pm = mContext.getPackageManager();
7191        int callingUid = Binder.getCallingUid();
7192        long ident = Binder.clearCallingIdentity();
7193
7194        // Compose the list of packages for this id to test against
7195        HashSet<String> packages = new HashSet<String>();
7196        String[] uidPackages = pm.getPackagesForUid(callingUid);
7197        for (int i = 0; i < uidPackages.length; i++) {
7198            packages.add(uidPackages[i]);
7199        }
7200
7201        synchronized(this) {
7202            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7203            try {
7204                if (localLOGV) Slog.v(TAG, "getAppTasks");
7205
7206                final int N = mRecentTasks.size();
7207                for (int i = 0; i < N; i++) {
7208                    TaskRecord tr = mRecentTasks.get(i);
7209                    // Skip tasks that are not created by the caller
7210                    if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) {
7211                        ActivityManager.RecentTaskInfo taskInfo =
7212                                createRecentTaskInfoFromTaskRecord(tr);
7213                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7214                        list.add(taskImpl);
7215                    }
7216                }
7217            } finally {
7218                Binder.restoreCallingIdentity(ident);
7219            }
7220            return list;
7221        }
7222    }
7223
7224    @Override
7225    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7226        final int callingUid = Binder.getCallingUid();
7227        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7228
7229        synchronized(this) {
7230            if (localLOGV) Slog.v(
7231                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7232
7233            final boolean allowed = checkCallingPermission(
7234                    android.Manifest.permission.GET_TASKS)
7235                    == PackageManager.PERMISSION_GRANTED;
7236            if (!allowed) {
7237                Slog.w(TAG, "getTasks: caller " + callingUid
7238                        + " does not hold GET_TASKS; limiting output");
7239            }
7240
7241            // TODO: Improve with MRU list from all ActivityStacks.
7242            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7243        }
7244
7245        return list;
7246    }
7247
7248    TaskRecord getMostRecentTask() {
7249        return mRecentTasks.get(0);
7250    }
7251
7252    /**
7253     * Creates a new RecentTaskInfo from a TaskRecord.
7254     */
7255    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7256        // Update the task description to reflect any changes in the task stack
7257        tr.updateTaskDescription();
7258
7259        // Compose the recent task info
7260        ActivityManager.RecentTaskInfo rti
7261                = new ActivityManager.RecentTaskInfo();
7262        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7263        rti.persistentId = tr.taskId;
7264        rti.baseIntent = new Intent(tr.getBaseIntent());
7265        rti.origActivity = tr.origActivity;
7266        rti.description = tr.lastDescription;
7267        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7268        rti.userId = tr.userId;
7269        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7270        rti.firstActiveTime = tr.firstActiveTime;
7271        rti.lastActiveTime = tr.lastActiveTime;
7272        return rti;
7273    }
7274
7275    @Override
7276    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
7277            int flags, int userId) {
7278        final int callingUid = Binder.getCallingUid();
7279        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7280                false, true, "getRecentTasks", null);
7281
7282        synchronized (this) {
7283            final boolean allowed = checkCallingPermission(
7284                    android.Manifest.permission.GET_TASKS)
7285                    == PackageManager.PERMISSION_GRANTED;
7286            if (!allowed) {
7287                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7288                        + " does not hold GET_TASKS; limiting output");
7289            }
7290            final boolean detailed = checkCallingPermission(
7291                    android.Manifest.permission.GET_DETAILED_TASKS)
7292                    == PackageManager.PERMISSION_GRANTED;
7293
7294            IPackageManager pm = AppGlobals.getPackageManager();
7295
7296            final int N = mRecentTasks.size();
7297            ArrayList<ActivityManager.RecentTaskInfo> res
7298                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7299                            maxNum < N ? maxNum : N);
7300
7301            final Set<Integer> includedUsers;
7302            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
7303                includedUsers = getProfileIdsLocked(userId);
7304            } else {
7305                includedUsers = new HashSet<Integer>();
7306            }
7307            includedUsers.add(Integer.valueOf(userId));
7308            for (int i=0; i<N && maxNum > 0; i++) {
7309                TaskRecord tr = mRecentTasks.get(i);
7310                // Only add calling user or related users recent tasks
7311                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7312
7313                // Return the entry if desired by the caller.  We always return
7314                // the first entry, because callers always expect this to be the
7315                // foreground app.  We may filter others if the caller has
7316                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7317                // we should exclude the entry.
7318
7319                if (i == 0
7320                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
7321                        || (tr.intent == null)
7322                        || ((tr.intent.getFlags()
7323                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
7324                    if (!allowed) {
7325                        // If the caller doesn't have the GET_TASKS permission, then only
7326                        // allow them to see a small subset of tasks -- their own and home.
7327                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7328                            continue;
7329                        }
7330                    }
7331                    if (tr.intent != null &&
7332                            (tr.intent.getFlags() & Intent.FLAG_ACTIVITY_AUTO_REMOVE_FROM_RECENTS)
7333                            != 0 && tr.getTopActivity() == null) {
7334                        // Don't include auto remove tasks that are finished or finishing.
7335                        continue;
7336                    }
7337
7338                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7339                    if (!detailed) {
7340                        rti.baseIntent.replaceExtras((Bundle)null);
7341                    }
7342
7343                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7344                        // Check whether this activity is currently available.
7345                        try {
7346                            if (rti.origActivity != null) {
7347                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7348                                        == null) {
7349                                    continue;
7350                                }
7351                            } else if (rti.baseIntent != null) {
7352                                if (pm.queryIntentActivities(rti.baseIntent,
7353                                        null, 0, userId) == null) {
7354                                    continue;
7355                                }
7356                            }
7357                        } catch (RemoteException e) {
7358                            // Will never happen.
7359                        }
7360                    }
7361
7362                    res.add(rti);
7363                    maxNum--;
7364                }
7365            }
7366            return res;
7367        }
7368    }
7369
7370    private TaskRecord recentTaskForIdLocked(int id) {
7371        final int N = mRecentTasks.size();
7372            for (int i=0; i<N; i++) {
7373                TaskRecord tr = mRecentTasks.get(i);
7374                if (tr.taskId == id) {
7375                    return tr;
7376                }
7377            }
7378            return null;
7379    }
7380
7381    @Override
7382    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7383        synchronized (this) {
7384            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7385                    "getTaskThumbnail()");
7386            TaskRecord tr = recentTaskForIdLocked(id);
7387            if (tr != null) {
7388                return tr.getTaskThumbnailLocked();
7389            }
7390        }
7391        return null;
7392    }
7393
7394    @Override
7395    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7396        synchronized (this) {
7397            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7398            if (r != null) {
7399                r.taskDescription = td;
7400                r.task.updateTaskDescription();
7401            }
7402        }
7403    }
7404
7405    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7406        if (!pr.killedByAm) {
7407            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7408            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7409                    pr.processName, pr.setAdj, reason);
7410            pr.killedByAm = true;
7411            Process.killProcessQuiet(pr.pid);
7412        }
7413    }
7414
7415    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7416        tr.disposeThumbnail();
7417        mRecentTasks.remove(tr);
7418        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7419        Intent baseIntent = new Intent(
7420                tr.intent != null ? tr.intent : tr.affinityIntent);
7421        ComponentName component = baseIntent.getComponent();
7422        if (component == null) {
7423            Slog.w(TAG, "Now component for base intent of task: " + tr);
7424            return;
7425        }
7426
7427        // Find any running services associated with this app.
7428        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7429
7430        if (killProcesses) {
7431            // Find any running processes associated with this app.
7432            final String pkg = component.getPackageName();
7433            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7434            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7435            for (int i=0; i<pmap.size(); i++) {
7436                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7437                for (int j=0; j<uids.size(); j++) {
7438                    ProcessRecord proc = uids.valueAt(j);
7439                    if (proc.userId != tr.userId) {
7440                        continue;
7441                    }
7442                    if (!proc.pkgList.containsKey(pkg)) {
7443                        continue;
7444                    }
7445                    procs.add(proc);
7446                }
7447            }
7448
7449            // Kill the running processes.
7450            for (int i=0; i<procs.size(); i++) {
7451                ProcessRecord pr = procs.get(i);
7452                if (pr == mHomeProcess) {
7453                    // Don't kill the home process along with tasks from the same package.
7454                    continue;
7455                }
7456                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7457                    killUnneededProcessLocked(pr, "remove task");
7458                } else {
7459                    pr.waitingToKill = "remove task";
7460                }
7461            }
7462        }
7463    }
7464
7465    /**
7466     * Removes the task with the specified task id.
7467     *
7468     * @param taskId Identifier of the task to be removed.
7469     * @param flags Additional operational flags.  May be 0 or
7470     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7471     * @return Returns true if the given task was found and removed.
7472     */
7473    private boolean removeTaskByIdLocked(int taskId, int flags) {
7474        TaskRecord tr = recentTaskForIdLocked(taskId);
7475        if (tr != null) {
7476            tr.removeTaskActivitiesLocked();
7477            cleanUpRemovedTaskLocked(tr, flags);
7478            if (tr.isPersistable) {
7479                notifyTaskPersisterLocked(tr, true);
7480            }
7481            return true;
7482        }
7483        return false;
7484    }
7485
7486    @Override
7487    public boolean removeTask(int taskId, int flags) {
7488        synchronized (this) {
7489            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7490                    "removeTask()");
7491            long ident = Binder.clearCallingIdentity();
7492            try {
7493                return removeTaskByIdLocked(taskId, flags);
7494            } finally {
7495                Binder.restoreCallingIdentity(ident);
7496            }
7497        }
7498    }
7499
7500    /**
7501     * TODO: Add mController hook
7502     */
7503    @Override
7504    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7505        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7506                "moveTaskToFront()");
7507
7508        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7509        synchronized(this) {
7510            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7511                    Binder.getCallingUid(), "Task to front")) {
7512                ActivityOptions.abort(options);
7513                return;
7514            }
7515            final long origId = Binder.clearCallingIdentity();
7516            try {
7517                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7518                if (task == null) {
7519                    return;
7520                }
7521                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7522                    mStackSupervisor.showLockTaskToast();
7523                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7524                    return;
7525                }
7526                final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
7527                if (prev != null && prev.isRecentsActivity()) {
7528                    task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
7529                }
7530                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7531            } finally {
7532                Binder.restoreCallingIdentity(origId);
7533            }
7534            ActivityOptions.abort(options);
7535        }
7536    }
7537
7538    @Override
7539    public void moveTaskToBack(int taskId) {
7540        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7541                "moveTaskToBack()");
7542
7543        synchronized(this) {
7544            TaskRecord tr = recentTaskForIdLocked(taskId);
7545            if (tr != null) {
7546                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7547                ActivityStack stack = tr.stack;
7548                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7549                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7550                            Binder.getCallingUid(), "Task to back")) {
7551                        return;
7552                    }
7553                }
7554                final long origId = Binder.clearCallingIdentity();
7555                try {
7556                    stack.moveTaskToBackLocked(taskId, null);
7557                } finally {
7558                    Binder.restoreCallingIdentity(origId);
7559                }
7560            }
7561        }
7562    }
7563
7564    /**
7565     * Moves an activity, and all of the other activities within the same task, to the bottom
7566     * of the history stack.  The activity's order within the task is unchanged.
7567     *
7568     * @param token A reference to the activity we wish to move
7569     * @param nonRoot If false then this only works if the activity is the root
7570     *                of a task; if true it will work for any activity in a task.
7571     * @return Returns true if the move completed, false if not.
7572     */
7573    @Override
7574    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7575        enforceNotIsolatedCaller("moveActivityTaskToBack");
7576        synchronized(this) {
7577            final long origId = Binder.clearCallingIdentity();
7578            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7579            if (taskId >= 0) {
7580                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7581            }
7582            Binder.restoreCallingIdentity(origId);
7583        }
7584        return false;
7585    }
7586
7587    @Override
7588    public void moveTaskBackwards(int task) {
7589        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7590                "moveTaskBackwards()");
7591
7592        synchronized(this) {
7593            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7594                    Binder.getCallingUid(), "Task backwards")) {
7595                return;
7596            }
7597            final long origId = Binder.clearCallingIdentity();
7598            moveTaskBackwardsLocked(task);
7599            Binder.restoreCallingIdentity(origId);
7600        }
7601    }
7602
7603    private final void moveTaskBackwardsLocked(int task) {
7604        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7605    }
7606
7607    @Override
7608    public IBinder getHomeActivityToken() throws RemoteException {
7609        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7610                "getHomeActivityToken()");
7611        synchronized (this) {
7612            return mStackSupervisor.getHomeActivityToken();
7613        }
7614    }
7615
7616    @Override
7617    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7618            IActivityContainerCallback callback) throws RemoteException {
7619        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7620                "createActivityContainer()");
7621        synchronized (this) {
7622            if (parentActivityToken == null) {
7623                throw new IllegalArgumentException("parent token must not be null");
7624            }
7625            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7626            if (r == null) {
7627                return null;
7628            }
7629            if (callback == null) {
7630                throw new IllegalArgumentException("callback must not be null");
7631            }
7632            return mStackSupervisor.createActivityContainer(r, callback);
7633        }
7634    }
7635
7636    @Override
7637    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7638        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7639                "deleteActivityContainer()");
7640        synchronized (this) {
7641            mStackSupervisor.deleteActivityContainer(container);
7642        }
7643    }
7644
7645    @Override
7646    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7647            throws RemoteException {
7648        synchronized (this) {
7649            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7650            if (stack != null) {
7651                return stack.mActivityContainer;
7652            }
7653            return null;
7654        }
7655    }
7656
7657    @Override
7658    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7659        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7660                "moveTaskToStack()");
7661        if (stackId == HOME_STACK_ID) {
7662            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7663                    new RuntimeException("here").fillInStackTrace());
7664        }
7665        synchronized (this) {
7666            long ident = Binder.clearCallingIdentity();
7667            try {
7668                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7669                        + stackId + " toTop=" + toTop);
7670                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7671            } finally {
7672                Binder.restoreCallingIdentity(ident);
7673            }
7674        }
7675    }
7676
7677    @Override
7678    public void resizeStack(int stackBoxId, Rect bounds) {
7679        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7680                "resizeStackBox()");
7681        long ident = Binder.clearCallingIdentity();
7682        try {
7683            mWindowManager.resizeStack(stackBoxId, bounds);
7684        } finally {
7685            Binder.restoreCallingIdentity(ident);
7686        }
7687    }
7688
7689    @Override
7690    public List<StackInfo> getAllStackInfos() {
7691        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7692                "getAllStackInfos()");
7693        long ident = Binder.clearCallingIdentity();
7694        try {
7695            synchronized (this) {
7696                return mStackSupervisor.getAllStackInfosLocked();
7697            }
7698        } finally {
7699            Binder.restoreCallingIdentity(ident);
7700        }
7701    }
7702
7703    @Override
7704    public StackInfo getStackInfo(int stackId) {
7705        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7706                "getStackInfo()");
7707        long ident = Binder.clearCallingIdentity();
7708        try {
7709            synchronized (this) {
7710                return mStackSupervisor.getStackInfoLocked(stackId);
7711            }
7712        } finally {
7713            Binder.restoreCallingIdentity(ident);
7714        }
7715    }
7716
7717    @Override
7718    public boolean isInHomeStack(int taskId) {
7719        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7720                "getStackInfo()");
7721        long ident = Binder.clearCallingIdentity();
7722        try {
7723            synchronized (this) {
7724                TaskRecord tr = recentTaskForIdLocked(taskId);
7725                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7726            }
7727        } finally {
7728            Binder.restoreCallingIdentity(ident);
7729        }
7730    }
7731
7732    @Override
7733    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7734        synchronized(this) {
7735            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7736        }
7737    }
7738
7739    private boolean isLockTaskAuthorized(String pkg) {
7740        final DevicePolicyManager dpm = (DevicePolicyManager)
7741                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7742        try {
7743            int uid = mContext.getPackageManager().getPackageUid(pkg,
7744                    Binder.getCallingUserHandle().getIdentifier());
7745            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
7746        } catch (NameNotFoundException e) {
7747            return false;
7748        }
7749    }
7750
7751    void startLockTaskMode(TaskRecord task) {
7752        final String pkg;
7753        synchronized (this) {
7754            pkg = task.intent.getComponent().getPackageName();
7755        }
7756        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
7757        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
7758            final TaskRecord taskRecord = task;
7759            mHandler.post(new Runnable() {
7760                @Override
7761                public void run() {
7762                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
7763                }
7764            });
7765            return;
7766        }
7767        long ident = Binder.clearCallingIdentity();
7768        try {
7769            synchronized (this) {
7770                // Since we lost lock on task, make sure it is still there.
7771                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7772                if (task != null) {
7773                    if (!isSystemInitiated
7774                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
7775                        throw new IllegalArgumentException("Invalid task, not in foreground");
7776                    }
7777                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
7778                }
7779            }
7780        } finally {
7781            Binder.restoreCallingIdentity(ident);
7782        }
7783    }
7784
7785    @Override
7786    public void startLockTaskMode(int taskId) {
7787        final TaskRecord task;
7788        long ident = Binder.clearCallingIdentity();
7789        try {
7790            synchronized (this) {
7791                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7792            }
7793        } finally {
7794            Binder.restoreCallingIdentity(ident);
7795        }
7796        if (task != null) {
7797            startLockTaskMode(task);
7798        }
7799    }
7800
7801    @Override
7802    public void startLockTaskMode(IBinder token) {
7803        final TaskRecord task;
7804        long ident = Binder.clearCallingIdentity();
7805        try {
7806            synchronized (this) {
7807                final ActivityRecord r = ActivityRecord.forToken(token);
7808                if (r == null) {
7809                    return;
7810                }
7811                task = r.task;
7812            }
7813        } finally {
7814            Binder.restoreCallingIdentity(ident);
7815        }
7816        if (task != null) {
7817            startLockTaskMode(task);
7818        }
7819    }
7820
7821    @Override
7822    public void startLockTaskModeOnCurrent() throws RemoteException {
7823        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7824        ActivityRecord r = null;
7825        synchronized (this) {
7826            r = mStackSupervisor.topRunningActivityLocked();
7827        }
7828        startLockTaskMode(r.task);
7829    }
7830
7831    @Override
7832    public void stopLockTaskMode() {
7833        // Verify that the user matches the package of the intent for the TaskRecord
7834        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
7835        // and stopLockTaskMode.
7836        final int callingUid = Binder.getCallingUid();
7837        if (callingUid != Process.SYSTEM_UID) {
7838            try {
7839                String pkg =
7840                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
7841                int uid = mContext.getPackageManager().getPackageUid(pkg,
7842                        Binder.getCallingUserHandle().getIdentifier());
7843                if (uid != callingUid) {
7844                    throw new SecurityException("Invalid uid, expected " + uid);
7845                }
7846            } catch (NameNotFoundException e) {
7847                Log.d(TAG, "stopLockTaskMode " + e);
7848                return;
7849            }
7850        }
7851        long ident = Binder.clearCallingIdentity();
7852        try {
7853            Log.d(TAG, "stopLockTaskMode");
7854            // Stop lock task
7855            synchronized (this) {
7856                mStackSupervisor.setLockTaskModeLocked(null, false);
7857            }
7858        } finally {
7859            Binder.restoreCallingIdentity(ident);
7860        }
7861    }
7862
7863    @Override
7864    public void stopLockTaskModeOnCurrent() throws RemoteException {
7865        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7866        long ident = Binder.clearCallingIdentity();
7867        try {
7868            stopLockTaskMode();
7869        } finally {
7870            Binder.restoreCallingIdentity(ident);
7871        }
7872    }
7873
7874    @Override
7875    public boolean isInLockTaskMode() {
7876        synchronized (this) {
7877            return mStackSupervisor.isInLockTaskMode();
7878        }
7879    }
7880
7881    // =========================================================
7882    // CONTENT PROVIDERS
7883    // =========================================================
7884
7885    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7886        List<ProviderInfo> providers = null;
7887        try {
7888            providers = AppGlobals.getPackageManager().
7889                queryContentProviders(app.processName, app.uid,
7890                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7891        } catch (RemoteException ex) {
7892        }
7893        if (DEBUG_MU)
7894            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7895        int userId = app.userId;
7896        if (providers != null) {
7897            int N = providers.size();
7898            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7899            for (int i=0; i<N; i++) {
7900                ProviderInfo cpi =
7901                    (ProviderInfo)providers.get(i);
7902                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7903                        cpi.name, cpi.flags);
7904                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7905                    // This is a singleton provider, but a user besides the
7906                    // default user is asking to initialize a process it runs
7907                    // in...  well, no, it doesn't actually run in this process,
7908                    // it runs in the process of the default user.  Get rid of it.
7909                    providers.remove(i);
7910                    N--;
7911                    i--;
7912                    continue;
7913                }
7914
7915                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7916                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7917                if (cpr == null) {
7918                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7919                    mProviderMap.putProviderByClass(comp, cpr);
7920                }
7921                if (DEBUG_MU)
7922                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7923                app.pubProviders.put(cpi.name, cpr);
7924                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7925                    // Don't add this if it is a platform component that is marked
7926                    // to run in multiple processes, because this is actually
7927                    // part of the framework so doesn't make sense to track as a
7928                    // separate apk in the process.
7929                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
7930                            mProcessStats);
7931                }
7932                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7933            }
7934        }
7935        return providers;
7936    }
7937
7938    /**
7939     * Check if {@link ProcessRecord} has a possible chance at accessing the
7940     * given {@link ProviderInfo}. Final permission checking is always done
7941     * in {@link ContentProvider}.
7942     */
7943    private final String checkContentProviderPermissionLocked(
7944            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
7945        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7946        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7947        boolean checkedGrants = false;
7948        if (checkUser) {
7949            // Looking for cross-user grants before enforcing the typical cross-users permissions
7950            if (UserHandle.getUserId(callingUid) != userId) {
7951                if (checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
7952                    return null;
7953                }
7954                checkedGrants = true;
7955            }
7956            userId = handleIncomingUser(callingPid, callingUid, userId,
7957                    false, false, "checkContentProviderPermissionLocked " + cpi.authority, null);
7958        }
7959        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7960                cpi.applicationInfo.uid, cpi.exported)
7961                == PackageManager.PERMISSION_GRANTED) {
7962            return null;
7963        }
7964        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7965                cpi.applicationInfo.uid, cpi.exported)
7966                == PackageManager.PERMISSION_GRANTED) {
7967            return null;
7968        }
7969
7970        PathPermission[] pps = cpi.pathPermissions;
7971        if (pps != null) {
7972            int i = pps.length;
7973            while (i > 0) {
7974                i--;
7975                PathPermission pp = pps[i];
7976                String pprperm = pp.getReadPermission();
7977                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
7978                        cpi.applicationInfo.uid, cpi.exported)
7979                        == PackageManager.PERMISSION_GRANTED) {
7980                    return null;
7981                }
7982                String ppwperm = pp.getWritePermission();
7983                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
7984                        cpi.applicationInfo.uid, cpi.exported)
7985                        == PackageManager.PERMISSION_GRANTED) {
7986                    return null;
7987                }
7988            }
7989        }
7990        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
7991            return null;
7992        }
7993
7994        String msg;
7995        if (!cpi.exported) {
7996            msg = "Permission Denial: opening provider " + cpi.name
7997                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7998                    + ", uid=" + callingUid + ") that is not exported from uid "
7999                    + cpi.applicationInfo.uid;
8000        } else {
8001            msg = "Permission Denial: opening provider " + cpi.name
8002                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8003                    + ", uid=" + callingUid + ") requires "
8004                    + cpi.readPermission + " or " + cpi.writePermission;
8005        }
8006        Slog.w(TAG, msg);
8007        return msg;
8008    }
8009
8010    /**
8011     * Returns if the ContentProvider has granted a uri to callingUid
8012     */
8013    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8014        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8015        if (perms != null) {
8016            for (GrantUri grantUri : perms.keySet()) {
8017                if (grantUri.sourceUserId == userId || !checkUser) {
8018                    if (matchesProvider(grantUri.uri, cpi)) {
8019                        return true;
8020                    }
8021                }
8022            }
8023        }
8024        return false;
8025    }
8026
8027    /**
8028     * Returns true if the uri authority is one of the authorities specified in the provider.
8029     */
8030    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8031        String uriAuth = uri.getAuthority();
8032        String cpiAuth = cpi.authority;
8033        if (cpiAuth.indexOf(';') == -1) {
8034            return cpiAuth.equals(uriAuth);
8035        }
8036        String[] cpiAuths = cpiAuth.split(";");
8037        int length = cpiAuths.length;
8038        for (int i = 0; i < length; i++) {
8039            if (cpiAuths[i].equals(uriAuth)) return true;
8040        }
8041        return false;
8042    }
8043
8044    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8045            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8046        if (r != null) {
8047            for (int i=0; i<r.conProviders.size(); i++) {
8048                ContentProviderConnection conn = r.conProviders.get(i);
8049                if (conn.provider == cpr) {
8050                    if (DEBUG_PROVIDER) Slog.v(TAG,
8051                            "Adding provider requested by "
8052                            + r.processName + " from process "
8053                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8054                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8055                    if (stable) {
8056                        conn.stableCount++;
8057                        conn.numStableIncs++;
8058                    } else {
8059                        conn.unstableCount++;
8060                        conn.numUnstableIncs++;
8061                    }
8062                    return conn;
8063                }
8064            }
8065            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8066            if (stable) {
8067                conn.stableCount = 1;
8068                conn.numStableIncs = 1;
8069            } else {
8070                conn.unstableCount = 1;
8071                conn.numUnstableIncs = 1;
8072            }
8073            cpr.connections.add(conn);
8074            r.conProviders.add(conn);
8075            return conn;
8076        }
8077        cpr.addExternalProcessHandleLocked(externalProcessToken);
8078        return null;
8079    }
8080
8081    boolean decProviderCountLocked(ContentProviderConnection conn,
8082            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8083        if (conn != null) {
8084            cpr = conn.provider;
8085            if (DEBUG_PROVIDER) Slog.v(TAG,
8086                    "Removing provider requested by "
8087                    + conn.client.processName + " from process "
8088                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8089                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8090            if (stable) {
8091                conn.stableCount--;
8092            } else {
8093                conn.unstableCount--;
8094            }
8095            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8096                cpr.connections.remove(conn);
8097                conn.client.conProviders.remove(conn);
8098                return true;
8099            }
8100            return false;
8101        }
8102        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8103        return false;
8104    }
8105
8106    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8107            String name, IBinder token, boolean stable, int userId) {
8108        ContentProviderRecord cpr;
8109        ContentProviderConnection conn = null;
8110        ProviderInfo cpi = null;
8111
8112        synchronized(this) {
8113            ProcessRecord r = null;
8114            if (caller != null) {
8115                r = getRecordForAppLocked(caller);
8116                if (r == null) {
8117                    throw new SecurityException(
8118                            "Unable to find app for caller " + caller
8119                          + " (pid=" + Binder.getCallingPid()
8120                          + ") when getting content provider " + name);
8121                }
8122            }
8123
8124            boolean checkCrossUser = true;
8125
8126            // First check if this content provider has been published...
8127            cpr = mProviderMap.getProviderByName(name, userId);
8128            // If that didn't work, check if it exists for user 0 and then
8129            // verify that it's a singleton provider before using it.
8130            if (cpr == null && userId != UserHandle.USER_OWNER) {
8131                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8132                if (cpr != null) {
8133                    cpi = cpr.info;
8134                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8135                            cpi.name, cpi.flags)
8136                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8137                        userId = UserHandle.USER_OWNER;
8138                        checkCrossUser = false;
8139                    } else {
8140                        cpr = null;
8141                        cpi = null;
8142                    }
8143                }
8144            }
8145
8146            boolean providerRunning = cpr != null;
8147            if (providerRunning) {
8148                cpi = cpr.info;
8149                String msg;
8150                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8151                        != null) {
8152                    throw new SecurityException(msg);
8153                }
8154
8155                if (r != null && cpr.canRunHere(r)) {
8156                    // This provider has been published or is in the process
8157                    // of being published...  but it is also allowed to run
8158                    // in the caller's process, so don't make a connection
8159                    // and just let the caller instantiate its own instance.
8160                    ContentProviderHolder holder = cpr.newHolder(null);
8161                    // don't give caller the provider object, it needs
8162                    // to make its own.
8163                    holder.provider = null;
8164                    return holder;
8165                }
8166
8167                final long origId = Binder.clearCallingIdentity();
8168
8169                // In this case the provider instance already exists, so we can
8170                // return it right away.
8171                conn = incProviderCountLocked(r, cpr, token, stable);
8172                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8173                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8174                        // If this is a perceptible app accessing the provider,
8175                        // make sure to count it as being accessed and thus
8176                        // back up on the LRU list.  This is good because
8177                        // content providers are often expensive to start.
8178                        updateLruProcessLocked(cpr.proc, false, null);
8179                    }
8180                }
8181
8182                if (cpr.proc != null) {
8183                    if (false) {
8184                        if (cpr.name.flattenToShortString().equals(
8185                                "com.android.providers.calendar/.CalendarProvider2")) {
8186                            Slog.v(TAG, "****************** KILLING "
8187                                + cpr.name.flattenToShortString());
8188                            Process.killProcess(cpr.proc.pid);
8189                        }
8190                    }
8191                    boolean success = updateOomAdjLocked(cpr.proc);
8192                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8193                    // NOTE: there is still a race here where a signal could be
8194                    // pending on the process even though we managed to update its
8195                    // adj level.  Not sure what to do about this, but at least
8196                    // the race is now smaller.
8197                    if (!success) {
8198                        // Uh oh...  it looks like the provider's process
8199                        // has been killed on us.  We need to wait for a new
8200                        // process to be started, and make sure its death
8201                        // doesn't kill our process.
8202                        Slog.i(TAG,
8203                                "Existing provider " + cpr.name.flattenToShortString()
8204                                + " is crashing; detaching " + r);
8205                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8206                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8207                        if (!lastRef) {
8208                            // This wasn't the last ref our process had on
8209                            // the provider...  we have now been killed, bail.
8210                            return null;
8211                        }
8212                        providerRunning = false;
8213                        conn = null;
8214                    }
8215                }
8216
8217                Binder.restoreCallingIdentity(origId);
8218            }
8219
8220            boolean singleton;
8221            if (!providerRunning) {
8222                try {
8223                    cpi = AppGlobals.getPackageManager().
8224                        resolveContentProvider(name,
8225                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8226                } catch (RemoteException ex) {
8227                }
8228                if (cpi == null) {
8229                    return null;
8230                }
8231                // If the provider is a singleton AND
8232                // (it's a call within the same user || the provider is a
8233                // privileged app)
8234                // Then allow connecting to the singleton provider
8235                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8236                        cpi.name, cpi.flags)
8237                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8238                if (singleton) {
8239                    userId = UserHandle.USER_OWNER;
8240                }
8241                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8242
8243                String msg;
8244                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8245                        != null) {
8246                    throw new SecurityException(msg);
8247                }
8248
8249                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8250                        && !cpi.processName.equals("system")) {
8251                    // If this content provider does not run in the system
8252                    // process, and the system is not yet ready to run other
8253                    // processes, then fail fast instead of hanging.
8254                    throw new IllegalArgumentException(
8255                            "Attempt to launch content provider before system ready");
8256                }
8257
8258                // Make sure that the user who owns this provider is started.  If not,
8259                // we don't want to allow it to run.
8260                if (mStartedUsers.get(userId) == null) {
8261                    Slog.w(TAG, "Unable to launch app "
8262                            + cpi.applicationInfo.packageName + "/"
8263                            + cpi.applicationInfo.uid + " for provider "
8264                            + name + ": user " + userId + " is stopped");
8265                    return null;
8266                }
8267
8268                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8269                cpr = mProviderMap.getProviderByClass(comp, userId);
8270                final boolean firstClass = cpr == null;
8271                if (firstClass) {
8272                    try {
8273                        ApplicationInfo ai =
8274                            AppGlobals.getPackageManager().
8275                                getApplicationInfo(
8276                                        cpi.applicationInfo.packageName,
8277                                        STOCK_PM_FLAGS, userId);
8278                        if (ai == null) {
8279                            Slog.w(TAG, "No package info for content provider "
8280                                    + cpi.name);
8281                            return null;
8282                        }
8283                        ai = getAppInfoForUser(ai, userId);
8284                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8285                    } catch (RemoteException ex) {
8286                        // pm is in same process, this will never happen.
8287                    }
8288                }
8289
8290                if (r != null && cpr.canRunHere(r)) {
8291                    // If this is a multiprocess provider, then just return its
8292                    // info and allow the caller to instantiate it.  Only do
8293                    // this if the provider is the same user as the caller's
8294                    // process, or can run as root (so can be in any process).
8295                    return cpr.newHolder(null);
8296                }
8297
8298                if (DEBUG_PROVIDER) {
8299                    RuntimeException e = new RuntimeException("here");
8300                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8301                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8302                }
8303
8304                // This is single process, and our app is now connecting to it.
8305                // See if we are already in the process of launching this
8306                // provider.
8307                final int N = mLaunchingProviders.size();
8308                int i;
8309                for (i=0; i<N; i++) {
8310                    if (mLaunchingProviders.get(i) == cpr) {
8311                        break;
8312                    }
8313                }
8314
8315                // If the provider is not already being launched, then get it
8316                // started.
8317                if (i >= N) {
8318                    final long origId = Binder.clearCallingIdentity();
8319
8320                    try {
8321                        // Content provider is now in use, its package can't be stopped.
8322                        try {
8323                            AppGlobals.getPackageManager().setPackageStoppedState(
8324                                    cpr.appInfo.packageName, false, userId);
8325                        } catch (RemoteException e) {
8326                        } catch (IllegalArgumentException e) {
8327                            Slog.w(TAG, "Failed trying to unstop package "
8328                                    + cpr.appInfo.packageName + ": " + e);
8329                        }
8330
8331                        // Use existing process if already started
8332                        ProcessRecord proc = getProcessRecordLocked(
8333                                cpi.processName, cpr.appInfo.uid, false);
8334                        if (proc != null && proc.thread != null) {
8335                            if (DEBUG_PROVIDER) {
8336                                Slog.d(TAG, "Installing in existing process " + proc);
8337                            }
8338                            proc.pubProviders.put(cpi.name, cpr);
8339                            try {
8340                                proc.thread.scheduleInstallProvider(cpi);
8341                            } catch (RemoteException e) {
8342                            }
8343                        } else {
8344                            proc = startProcessLocked(cpi.processName,
8345                                    cpr.appInfo, false, 0, "content provider",
8346                                    new ComponentName(cpi.applicationInfo.packageName,
8347                                            cpi.name), false, false, false);
8348                            if (proc == null) {
8349                                Slog.w(TAG, "Unable to launch app "
8350                                        + cpi.applicationInfo.packageName + "/"
8351                                        + cpi.applicationInfo.uid + " for provider "
8352                                        + name + ": process is bad");
8353                                return null;
8354                            }
8355                        }
8356                        cpr.launchingApp = proc;
8357                        mLaunchingProviders.add(cpr);
8358                    } finally {
8359                        Binder.restoreCallingIdentity(origId);
8360                    }
8361                }
8362
8363                // Make sure the provider is published (the same provider class
8364                // may be published under multiple names).
8365                if (firstClass) {
8366                    mProviderMap.putProviderByClass(comp, cpr);
8367                }
8368
8369                mProviderMap.putProviderByName(name, cpr);
8370                conn = incProviderCountLocked(r, cpr, token, stable);
8371                if (conn != null) {
8372                    conn.waiting = true;
8373                }
8374            }
8375        }
8376
8377        // Wait for the provider to be published...
8378        synchronized (cpr) {
8379            while (cpr.provider == null) {
8380                if (cpr.launchingApp == null) {
8381                    Slog.w(TAG, "Unable to launch app "
8382                            + cpi.applicationInfo.packageName + "/"
8383                            + cpi.applicationInfo.uid + " for provider "
8384                            + name + ": launching app became null");
8385                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8386                            UserHandle.getUserId(cpi.applicationInfo.uid),
8387                            cpi.applicationInfo.packageName,
8388                            cpi.applicationInfo.uid, name);
8389                    return null;
8390                }
8391                try {
8392                    if (DEBUG_MU) {
8393                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8394                                + cpr.launchingApp);
8395                    }
8396                    if (conn != null) {
8397                        conn.waiting = true;
8398                    }
8399                    cpr.wait();
8400                } catch (InterruptedException ex) {
8401                } finally {
8402                    if (conn != null) {
8403                        conn.waiting = false;
8404                    }
8405                }
8406            }
8407        }
8408        return cpr != null ? cpr.newHolder(conn) : null;
8409    }
8410
8411    @Override
8412    public final ContentProviderHolder getContentProvider(
8413            IApplicationThread caller, String name, int userId, boolean stable) {
8414        enforceNotIsolatedCaller("getContentProvider");
8415        if (caller == null) {
8416            String msg = "null IApplicationThread when getting content provider "
8417                    + name;
8418            Slog.w(TAG, msg);
8419            throw new SecurityException(msg);
8420        }
8421        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8422        // with cross-user grant.
8423        return getContentProviderImpl(caller, name, null, stable, userId);
8424    }
8425
8426    public ContentProviderHolder getContentProviderExternal(
8427            String name, int userId, IBinder token) {
8428        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8429            "Do not have permission in call getContentProviderExternal()");
8430        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8431                false, true, "getContentProvider", null);
8432        return getContentProviderExternalUnchecked(name, token, userId);
8433    }
8434
8435    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8436            IBinder token, int userId) {
8437        return getContentProviderImpl(null, name, token, true, userId);
8438    }
8439
8440    /**
8441     * Drop a content provider from a ProcessRecord's bookkeeping
8442     */
8443    public void removeContentProvider(IBinder connection, boolean stable) {
8444        enforceNotIsolatedCaller("removeContentProvider");
8445        long ident = Binder.clearCallingIdentity();
8446        try {
8447            synchronized (this) {
8448                ContentProviderConnection conn;
8449                try {
8450                    conn = (ContentProviderConnection)connection;
8451                } catch (ClassCastException e) {
8452                    String msg ="removeContentProvider: " + connection
8453                            + " not a ContentProviderConnection";
8454                    Slog.w(TAG, msg);
8455                    throw new IllegalArgumentException(msg);
8456                }
8457                if (conn == null) {
8458                    throw new NullPointerException("connection is null");
8459                }
8460                if (decProviderCountLocked(conn, null, null, stable)) {
8461                    updateOomAdjLocked();
8462                }
8463            }
8464        } finally {
8465            Binder.restoreCallingIdentity(ident);
8466        }
8467    }
8468
8469    public void removeContentProviderExternal(String name, IBinder token) {
8470        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8471            "Do not have permission in call removeContentProviderExternal()");
8472        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8473    }
8474
8475    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8476        synchronized (this) {
8477            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8478            if(cpr == null) {
8479                //remove from mProvidersByClass
8480                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8481                return;
8482            }
8483
8484            //update content provider record entry info
8485            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8486            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8487            if (localCpr.hasExternalProcessHandles()) {
8488                if (localCpr.removeExternalProcessHandleLocked(token)) {
8489                    updateOomAdjLocked();
8490                } else {
8491                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8492                            + " with no external reference for token: "
8493                            + token + ".");
8494                }
8495            } else {
8496                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8497                        + " with no external references.");
8498            }
8499        }
8500    }
8501
8502    public final void publishContentProviders(IApplicationThread caller,
8503            List<ContentProviderHolder> providers) {
8504        if (providers == null) {
8505            return;
8506        }
8507
8508        enforceNotIsolatedCaller("publishContentProviders");
8509        synchronized (this) {
8510            final ProcessRecord r = getRecordForAppLocked(caller);
8511            if (DEBUG_MU)
8512                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8513            if (r == null) {
8514                throw new SecurityException(
8515                        "Unable to find app for caller " + caller
8516                      + " (pid=" + Binder.getCallingPid()
8517                      + ") when publishing content providers");
8518            }
8519
8520            final long origId = Binder.clearCallingIdentity();
8521
8522            final int N = providers.size();
8523            for (int i=0; i<N; i++) {
8524                ContentProviderHolder src = providers.get(i);
8525                if (src == null || src.info == null || src.provider == null) {
8526                    continue;
8527                }
8528                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8529                if (DEBUG_MU)
8530                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8531                if (dst != null) {
8532                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8533                    mProviderMap.putProviderByClass(comp, dst);
8534                    String names[] = dst.info.authority.split(";");
8535                    for (int j = 0; j < names.length; j++) {
8536                        mProviderMap.putProviderByName(names[j], dst);
8537                    }
8538
8539                    int NL = mLaunchingProviders.size();
8540                    int j;
8541                    for (j=0; j<NL; j++) {
8542                        if (mLaunchingProviders.get(j) == dst) {
8543                            mLaunchingProviders.remove(j);
8544                            j--;
8545                            NL--;
8546                        }
8547                    }
8548                    synchronized (dst) {
8549                        dst.provider = src.provider;
8550                        dst.proc = r;
8551                        dst.notifyAll();
8552                    }
8553                    updateOomAdjLocked(r);
8554                }
8555            }
8556
8557            Binder.restoreCallingIdentity(origId);
8558        }
8559    }
8560
8561    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8562        ContentProviderConnection conn;
8563        try {
8564            conn = (ContentProviderConnection)connection;
8565        } catch (ClassCastException e) {
8566            String msg ="refContentProvider: " + connection
8567                    + " not a ContentProviderConnection";
8568            Slog.w(TAG, msg);
8569            throw new IllegalArgumentException(msg);
8570        }
8571        if (conn == null) {
8572            throw new NullPointerException("connection is null");
8573        }
8574
8575        synchronized (this) {
8576            if (stable > 0) {
8577                conn.numStableIncs += stable;
8578            }
8579            stable = conn.stableCount + stable;
8580            if (stable < 0) {
8581                throw new IllegalStateException("stableCount < 0: " + stable);
8582            }
8583
8584            if (unstable > 0) {
8585                conn.numUnstableIncs += unstable;
8586            }
8587            unstable = conn.unstableCount + unstable;
8588            if (unstable < 0) {
8589                throw new IllegalStateException("unstableCount < 0: " + unstable);
8590            }
8591
8592            if ((stable+unstable) <= 0) {
8593                throw new IllegalStateException("ref counts can't go to zero here: stable="
8594                        + stable + " unstable=" + unstable);
8595            }
8596            conn.stableCount = stable;
8597            conn.unstableCount = unstable;
8598            return !conn.dead;
8599        }
8600    }
8601
8602    public void unstableProviderDied(IBinder connection) {
8603        ContentProviderConnection conn;
8604        try {
8605            conn = (ContentProviderConnection)connection;
8606        } catch (ClassCastException e) {
8607            String msg ="refContentProvider: " + connection
8608                    + " not a ContentProviderConnection";
8609            Slog.w(TAG, msg);
8610            throw new IllegalArgumentException(msg);
8611        }
8612        if (conn == null) {
8613            throw new NullPointerException("connection is null");
8614        }
8615
8616        // Safely retrieve the content provider associated with the connection.
8617        IContentProvider provider;
8618        synchronized (this) {
8619            provider = conn.provider.provider;
8620        }
8621
8622        if (provider == null) {
8623            // Um, yeah, we're way ahead of you.
8624            return;
8625        }
8626
8627        // Make sure the caller is being honest with us.
8628        if (provider.asBinder().pingBinder()) {
8629            // Er, no, still looks good to us.
8630            synchronized (this) {
8631                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8632                        + " says " + conn + " died, but we don't agree");
8633                return;
8634            }
8635        }
8636
8637        // Well look at that!  It's dead!
8638        synchronized (this) {
8639            if (conn.provider.provider != provider) {
8640                // But something changed...  good enough.
8641                return;
8642            }
8643
8644            ProcessRecord proc = conn.provider.proc;
8645            if (proc == null || proc.thread == null) {
8646                // Seems like the process is already cleaned up.
8647                return;
8648            }
8649
8650            // As far as we're concerned, this is just like receiving a
8651            // death notification...  just a bit prematurely.
8652            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8653                    + ") early provider death");
8654            final long ident = Binder.clearCallingIdentity();
8655            try {
8656                appDiedLocked(proc, proc.pid, proc.thread);
8657            } finally {
8658                Binder.restoreCallingIdentity(ident);
8659            }
8660        }
8661    }
8662
8663    @Override
8664    public void appNotRespondingViaProvider(IBinder connection) {
8665        enforceCallingPermission(
8666                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8667
8668        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8669        if (conn == null) {
8670            Slog.w(TAG, "ContentProviderConnection is null");
8671            return;
8672        }
8673
8674        final ProcessRecord host = conn.provider.proc;
8675        if (host == null) {
8676            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8677            return;
8678        }
8679
8680        final long token = Binder.clearCallingIdentity();
8681        try {
8682            appNotResponding(host, null, null, false, "ContentProvider not responding");
8683        } finally {
8684            Binder.restoreCallingIdentity(token);
8685        }
8686    }
8687
8688    public final void installSystemProviders() {
8689        List<ProviderInfo> providers;
8690        synchronized (this) {
8691            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8692            providers = generateApplicationProvidersLocked(app);
8693            if (providers != null) {
8694                for (int i=providers.size()-1; i>=0; i--) {
8695                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8696                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8697                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8698                                + ": not system .apk");
8699                        providers.remove(i);
8700                    }
8701                }
8702            }
8703        }
8704        if (providers != null) {
8705            mSystemThread.installSystemProviders(providers);
8706        }
8707
8708        mCoreSettingsObserver = new CoreSettingsObserver(this);
8709
8710        mUsageStatsService.monitorPackages();
8711    }
8712
8713    /**
8714     * Allows app to retrieve the MIME type of a URI without having permission
8715     * to access its content provider.
8716     *
8717     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8718     *
8719     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8720     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8721     */
8722    public String getProviderMimeType(Uri uri, int userId) {
8723        enforceNotIsolatedCaller("getProviderMimeType");
8724        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8725                userId, false, true, "getProviderMimeType", null);
8726        final String name = uri.getAuthority();
8727        final long ident = Binder.clearCallingIdentity();
8728        ContentProviderHolder holder = null;
8729
8730        try {
8731            holder = getContentProviderExternalUnchecked(name, null, userId);
8732            if (holder != null) {
8733                return holder.provider.getType(uri);
8734            }
8735        } catch (RemoteException e) {
8736            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8737            return null;
8738        } finally {
8739            if (holder != null) {
8740                removeContentProviderExternalUnchecked(name, null, userId);
8741            }
8742            Binder.restoreCallingIdentity(ident);
8743        }
8744
8745        return null;
8746    }
8747
8748    // =========================================================
8749    // GLOBAL MANAGEMENT
8750    // =========================================================
8751
8752    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8753            boolean isolated) {
8754        String proc = customProcess != null ? customProcess : info.processName;
8755        BatteryStatsImpl.Uid.Proc ps = null;
8756        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8757        int uid = info.uid;
8758        if (isolated) {
8759            int userId = UserHandle.getUserId(uid);
8760            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8761            while (true) {
8762                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8763                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8764                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8765                }
8766                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8767                mNextIsolatedProcessUid++;
8768                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8769                    // No process for this uid, use it.
8770                    break;
8771                }
8772                stepsLeft--;
8773                if (stepsLeft <= 0) {
8774                    return null;
8775                }
8776            }
8777        }
8778        return new ProcessRecord(stats, info, proc, uid);
8779    }
8780
8781    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
8782            String abiOverride) {
8783        ProcessRecord app;
8784        if (!isolated) {
8785            app = getProcessRecordLocked(info.processName, info.uid, true);
8786        } else {
8787            app = null;
8788        }
8789
8790        if (app == null) {
8791            app = newProcessRecordLocked(info, null, isolated);
8792            mProcessNames.put(info.processName, app.uid, app);
8793            if (isolated) {
8794                mIsolatedProcesses.put(app.uid, app);
8795            }
8796            updateLruProcessLocked(app, false, null);
8797            updateOomAdjLocked();
8798        }
8799
8800        // This package really, really can not be stopped.
8801        try {
8802            AppGlobals.getPackageManager().setPackageStoppedState(
8803                    info.packageName, false, UserHandle.getUserId(app.uid));
8804        } catch (RemoteException e) {
8805        } catch (IllegalArgumentException e) {
8806            Slog.w(TAG, "Failed trying to unstop package "
8807                    + info.packageName + ": " + e);
8808        }
8809
8810        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8811                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8812            app.persistent = true;
8813            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8814        }
8815        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8816            mPersistentStartingProcesses.add(app);
8817            startProcessLocked(app, "added application", app.processName,
8818                    abiOverride);
8819        }
8820
8821        return app;
8822    }
8823
8824    public void unhandledBack() {
8825        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8826                "unhandledBack()");
8827
8828        synchronized(this) {
8829            final long origId = Binder.clearCallingIdentity();
8830            try {
8831                getFocusedStack().unhandledBackLocked();
8832            } finally {
8833                Binder.restoreCallingIdentity(origId);
8834            }
8835        }
8836    }
8837
8838    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8839        enforceNotIsolatedCaller("openContentUri");
8840        final int userId = UserHandle.getCallingUserId();
8841        String name = uri.getAuthority();
8842        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8843        ParcelFileDescriptor pfd = null;
8844        if (cph != null) {
8845            // We record the binder invoker's uid in thread-local storage before
8846            // going to the content provider to open the file.  Later, in the code
8847            // that handles all permissions checks, we look for this uid and use
8848            // that rather than the Activity Manager's own uid.  The effect is that
8849            // we do the check against the caller's permissions even though it looks
8850            // to the content provider like the Activity Manager itself is making
8851            // the request.
8852            sCallerIdentity.set(new Identity(
8853                    Binder.getCallingPid(), Binder.getCallingUid()));
8854            try {
8855                pfd = cph.provider.openFile(null, uri, "r", null);
8856            } catch (FileNotFoundException e) {
8857                // do nothing; pfd will be returned null
8858            } finally {
8859                // Ensure that whatever happens, we clean up the identity state
8860                sCallerIdentity.remove();
8861            }
8862
8863            // We've got the fd now, so we're done with the provider.
8864            removeContentProviderExternalUnchecked(name, null, userId);
8865        } else {
8866            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8867        }
8868        return pfd;
8869    }
8870
8871    // Actually is sleeping or shutting down or whatever else in the future
8872    // is an inactive state.
8873    public boolean isSleepingOrShuttingDown() {
8874        return mSleeping || mShuttingDown;
8875    }
8876
8877    public boolean isSleeping() {
8878        return mSleeping;
8879    }
8880
8881    void goingToSleep() {
8882        synchronized(this) {
8883            mWentToSleep = true;
8884            updateEventDispatchingLocked();
8885            goToSleepIfNeededLocked();
8886        }
8887    }
8888
8889    void finishRunningVoiceLocked() {
8890        if (mRunningVoice) {
8891            mRunningVoice = false;
8892            goToSleepIfNeededLocked();
8893        }
8894    }
8895
8896    void goToSleepIfNeededLocked() {
8897        if (mWentToSleep && !mRunningVoice) {
8898            if (!mSleeping) {
8899                mSleeping = true;
8900                mStackSupervisor.goingToSleepLocked();
8901
8902                // Initialize the wake times of all processes.
8903                checkExcessivePowerUsageLocked(false);
8904                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8905                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8906                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8907            }
8908        }
8909    }
8910
8911    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
8912        mTaskPersister.notify(task, flush);
8913    }
8914
8915    @Override
8916    public boolean shutdown(int timeout) {
8917        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8918                != PackageManager.PERMISSION_GRANTED) {
8919            throw new SecurityException("Requires permission "
8920                    + android.Manifest.permission.SHUTDOWN);
8921        }
8922
8923        boolean timedout = false;
8924
8925        synchronized(this) {
8926            mShuttingDown = true;
8927            updateEventDispatchingLocked();
8928            timedout = mStackSupervisor.shutdownLocked(timeout);
8929        }
8930
8931        mAppOpsService.shutdown();
8932        mUsageStatsService.shutdown();
8933        mBatteryStatsService.shutdown();
8934        synchronized (this) {
8935            mProcessStats.shutdownLocked();
8936        }
8937        notifyTaskPersisterLocked(null, true);
8938
8939        return timedout;
8940    }
8941
8942    public final void activitySlept(IBinder token) {
8943        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8944
8945        final long origId = Binder.clearCallingIdentity();
8946
8947        synchronized (this) {
8948            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8949            if (r != null) {
8950                mStackSupervisor.activitySleptLocked(r);
8951            }
8952        }
8953
8954        Binder.restoreCallingIdentity(origId);
8955    }
8956
8957    void logLockScreen(String msg) {
8958        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8959                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8960                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8961                mStackSupervisor.mDismissKeyguardOnNextActivity);
8962    }
8963
8964    private void comeOutOfSleepIfNeededLocked() {
8965        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
8966            if (mSleeping) {
8967                mSleeping = false;
8968                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8969            }
8970        }
8971    }
8972
8973    void wakingUp() {
8974        synchronized(this) {
8975            mWentToSleep = false;
8976            updateEventDispatchingLocked();
8977            comeOutOfSleepIfNeededLocked();
8978        }
8979    }
8980
8981    void startRunningVoiceLocked() {
8982        if (!mRunningVoice) {
8983            mRunningVoice = true;
8984            comeOutOfSleepIfNeededLocked();
8985        }
8986    }
8987
8988    private void updateEventDispatchingLocked() {
8989        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8990    }
8991
8992    public void setLockScreenShown(boolean shown) {
8993        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8994                != PackageManager.PERMISSION_GRANTED) {
8995            throw new SecurityException("Requires permission "
8996                    + android.Manifest.permission.DEVICE_POWER);
8997        }
8998
8999        synchronized(this) {
9000            long ident = Binder.clearCallingIdentity();
9001            try {
9002                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9003                mLockScreenShown = shown;
9004                comeOutOfSleepIfNeededLocked();
9005            } finally {
9006                Binder.restoreCallingIdentity(ident);
9007            }
9008        }
9009    }
9010
9011    public void stopAppSwitches() {
9012        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9013                != PackageManager.PERMISSION_GRANTED) {
9014            throw new SecurityException("Requires permission "
9015                    + android.Manifest.permission.STOP_APP_SWITCHES);
9016        }
9017
9018        synchronized(this) {
9019            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9020                    + APP_SWITCH_DELAY_TIME;
9021            mDidAppSwitch = false;
9022            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9023            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9024            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9025        }
9026    }
9027
9028    public void resumeAppSwitches() {
9029        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9030                != PackageManager.PERMISSION_GRANTED) {
9031            throw new SecurityException("Requires permission "
9032                    + android.Manifest.permission.STOP_APP_SWITCHES);
9033        }
9034
9035        synchronized(this) {
9036            // Note that we don't execute any pending app switches... we will
9037            // let those wait until either the timeout, or the next start
9038            // activity request.
9039            mAppSwitchesAllowedTime = 0;
9040        }
9041    }
9042
9043    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9044            String name) {
9045        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9046            return true;
9047        }
9048
9049        final int perm = checkComponentPermission(
9050                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9051                callingUid, -1, true);
9052        if (perm == PackageManager.PERMISSION_GRANTED) {
9053            return true;
9054        }
9055
9056        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9057        return false;
9058    }
9059
9060    public void setDebugApp(String packageName, boolean waitForDebugger,
9061            boolean persistent) {
9062        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9063                "setDebugApp()");
9064
9065        long ident = Binder.clearCallingIdentity();
9066        try {
9067            // Note that this is not really thread safe if there are multiple
9068            // callers into it at the same time, but that's not a situation we
9069            // care about.
9070            if (persistent) {
9071                final ContentResolver resolver = mContext.getContentResolver();
9072                Settings.Global.putString(
9073                    resolver, Settings.Global.DEBUG_APP,
9074                    packageName);
9075                Settings.Global.putInt(
9076                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9077                    waitForDebugger ? 1 : 0);
9078            }
9079
9080            synchronized (this) {
9081                if (!persistent) {
9082                    mOrigDebugApp = mDebugApp;
9083                    mOrigWaitForDebugger = mWaitForDebugger;
9084                }
9085                mDebugApp = packageName;
9086                mWaitForDebugger = waitForDebugger;
9087                mDebugTransient = !persistent;
9088                if (packageName != null) {
9089                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9090                            false, UserHandle.USER_ALL, "set debug app");
9091                }
9092            }
9093        } finally {
9094            Binder.restoreCallingIdentity(ident);
9095        }
9096    }
9097
9098    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9099        synchronized (this) {
9100            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9101            if (!isDebuggable) {
9102                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9103                    throw new SecurityException("Process not debuggable: " + app.packageName);
9104                }
9105            }
9106
9107            mOpenGlTraceApp = processName;
9108        }
9109    }
9110
9111    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9112            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9113        synchronized (this) {
9114            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9115            if (!isDebuggable) {
9116                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9117                    throw new SecurityException("Process not debuggable: " + app.packageName);
9118                }
9119            }
9120            mProfileApp = processName;
9121            mProfileFile = profileFile;
9122            if (mProfileFd != null) {
9123                try {
9124                    mProfileFd.close();
9125                } catch (IOException e) {
9126                }
9127                mProfileFd = null;
9128            }
9129            mProfileFd = profileFd;
9130            mProfileType = 0;
9131            mAutoStopProfiler = autoStopProfiler;
9132        }
9133    }
9134
9135    @Override
9136    public void setAlwaysFinish(boolean enabled) {
9137        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9138                "setAlwaysFinish()");
9139
9140        Settings.Global.putInt(
9141                mContext.getContentResolver(),
9142                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9143
9144        synchronized (this) {
9145            mAlwaysFinishActivities = enabled;
9146        }
9147    }
9148
9149    @Override
9150    public void setActivityController(IActivityController controller) {
9151        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9152                "setActivityController()");
9153        synchronized (this) {
9154            mController = controller;
9155            Watchdog.getInstance().setActivityController(controller);
9156        }
9157    }
9158
9159    @Override
9160    public void setUserIsMonkey(boolean userIsMonkey) {
9161        synchronized (this) {
9162            synchronized (mPidsSelfLocked) {
9163                final int callingPid = Binder.getCallingPid();
9164                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9165                if (precessRecord == null) {
9166                    throw new SecurityException("Unknown process: " + callingPid);
9167                }
9168                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9169                    throw new SecurityException("Only an instrumentation process "
9170                            + "with a UiAutomation can call setUserIsMonkey");
9171                }
9172            }
9173            mUserIsMonkey = userIsMonkey;
9174        }
9175    }
9176
9177    @Override
9178    public boolean isUserAMonkey() {
9179        synchronized (this) {
9180            // If there is a controller also implies the user is a monkey.
9181            return (mUserIsMonkey || mController != null);
9182        }
9183    }
9184
9185    public void requestBugReport() {
9186        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9187        SystemProperties.set("ctl.start", "bugreport");
9188    }
9189
9190    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9191        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9192    }
9193
9194    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9195        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9196            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9197        }
9198        return KEY_DISPATCHING_TIMEOUT;
9199    }
9200
9201    @Override
9202    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9203        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9204                != PackageManager.PERMISSION_GRANTED) {
9205            throw new SecurityException("Requires permission "
9206                    + android.Manifest.permission.FILTER_EVENTS);
9207        }
9208        ProcessRecord proc;
9209        long timeout;
9210        synchronized (this) {
9211            synchronized (mPidsSelfLocked) {
9212                proc = mPidsSelfLocked.get(pid);
9213            }
9214            timeout = getInputDispatchingTimeoutLocked(proc);
9215        }
9216
9217        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9218            return -1;
9219        }
9220
9221        return timeout;
9222    }
9223
9224    /**
9225     * Handle input dispatching timeouts.
9226     * Returns whether input dispatching should be aborted or not.
9227     */
9228    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9229            final ActivityRecord activity, final ActivityRecord parent,
9230            final boolean aboveSystem, String reason) {
9231        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9232                != PackageManager.PERMISSION_GRANTED) {
9233            throw new SecurityException("Requires permission "
9234                    + android.Manifest.permission.FILTER_EVENTS);
9235        }
9236
9237        final String annotation;
9238        if (reason == null) {
9239            annotation = "Input dispatching timed out";
9240        } else {
9241            annotation = "Input dispatching timed out (" + reason + ")";
9242        }
9243
9244        if (proc != null) {
9245            synchronized (this) {
9246                if (proc.debugging) {
9247                    return false;
9248                }
9249
9250                if (mDidDexOpt) {
9251                    // Give more time since we were dexopting.
9252                    mDidDexOpt = false;
9253                    return false;
9254                }
9255
9256                if (proc.instrumentationClass != null) {
9257                    Bundle info = new Bundle();
9258                    info.putString("shortMsg", "keyDispatchingTimedOut");
9259                    info.putString("longMsg", annotation);
9260                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9261                    return true;
9262                }
9263            }
9264            mHandler.post(new Runnable() {
9265                @Override
9266                public void run() {
9267                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9268                }
9269            });
9270        }
9271
9272        return true;
9273    }
9274
9275    public Bundle getAssistContextExtras(int requestType) {
9276        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9277                "getAssistContextExtras()");
9278        PendingAssistExtras pae;
9279        Bundle extras = new Bundle();
9280        synchronized (this) {
9281            ActivityRecord activity = getFocusedStack().mResumedActivity;
9282            if (activity == null) {
9283                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9284                return null;
9285            }
9286            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9287            if (activity.app == null || activity.app.thread == null) {
9288                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9289                return extras;
9290            }
9291            if (activity.app.pid == Binder.getCallingPid()) {
9292                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9293                return extras;
9294            }
9295            pae = new PendingAssistExtras(activity);
9296            try {
9297                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9298                        requestType);
9299                mPendingAssistExtras.add(pae);
9300                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9301            } catch (RemoteException e) {
9302                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9303                return extras;
9304            }
9305        }
9306        synchronized (pae) {
9307            while (!pae.haveResult) {
9308                try {
9309                    pae.wait();
9310                } catch (InterruptedException e) {
9311                }
9312            }
9313            if (pae.result != null) {
9314                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9315            }
9316        }
9317        synchronized (this) {
9318            mPendingAssistExtras.remove(pae);
9319            mHandler.removeCallbacks(pae);
9320        }
9321        return extras;
9322    }
9323
9324    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9325        PendingAssistExtras pae = (PendingAssistExtras)token;
9326        synchronized (pae) {
9327            pae.result = extras;
9328            pae.haveResult = true;
9329            pae.notifyAll();
9330        }
9331    }
9332
9333    public void registerProcessObserver(IProcessObserver observer) {
9334        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9335                "registerProcessObserver()");
9336        synchronized (this) {
9337            mProcessObservers.register(observer);
9338        }
9339    }
9340
9341    @Override
9342    public void unregisterProcessObserver(IProcessObserver observer) {
9343        synchronized (this) {
9344            mProcessObservers.unregister(observer);
9345        }
9346    }
9347
9348    @Override
9349    public boolean convertFromTranslucent(IBinder token) {
9350        final long origId = Binder.clearCallingIdentity();
9351        try {
9352            synchronized (this) {
9353                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9354                if (r == null) {
9355                    return false;
9356                }
9357                if (r.changeWindowTranslucency(true)) {
9358                    mWindowManager.setAppFullscreen(token, true);
9359                    r.task.stack.releaseMediaResources();
9360                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9361                    return true;
9362                }
9363                return false;
9364            }
9365        } finally {
9366            Binder.restoreCallingIdentity(origId);
9367        }
9368    }
9369
9370    @Override
9371    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9372        final long origId = Binder.clearCallingIdentity();
9373        try {
9374            synchronized (this) {
9375                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9376                if (r == null) {
9377                    return false;
9378                }
9379                if (r.changeWindowTranslucency(false)) {
9380                    r.task.stack.convertToTranslucent(r, options);
9381                    mWindowManager.setAppFullscreen(token, false);
9382                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9383                    return true;
9384                } else {
9385                    r.task.stack.mReturningActivityOptions = options;
9386                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9387                    return false;
9388                }
9389            }
9390        } finally {
9391            Binder.restoreCallingIdentity(origId);
9392        }
9393    }
9394
9395    @Override
9396    public boolean setMediaPlaying(IBinder token, boolean playing) {
9397        final long origId = Binder.clearCallingIdentity();
9398        try {
9399            synchronized (this) {
9400                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9401                if (r != null) {
9402                    return mStackSupervisor.setMediaPlayingLocked(r, playing);
9403                }
9404            }
9405            return false;
9406        } finally {
9407            Binder.restoreCallingIdentity(origId);
9408        }
9409    }
9410
9411    @Override
9412    public boolean isBackgroundMediaPlaying(IBinder token) {
9413        final long origId = Binder.clearCallingIdentity();
9414        try {
9415            synchronized (this) {
9416                final ActivityStack stack = ActivityRecord.getStackLocked(token);
9417                final boolean playing = stack == null ? false : stack.isMediaPlaying();
9418                if (ActivityStackSupervisor.DEBUG_MEDIA_VISIBILITY) Slog.d(TAG,
9419                        "isBackgroundMediaPlaying: stack=" + stack + " playing=" + playing);
9420                return playing;
9421            }
9422        } finally {
9423            Binder.restoreCallingIdentity(origId);
9424        }
9425    }
9426
9427    @Override
9428    public ActivityOptions getActivityOptions(IBinder token) {
9429        final long origId = Binder.clearCallingIdentity();
9430        try {
9431            synchronized (this) {
9432                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9433                if (r != null) {
9434                    final ActivityOptions activityOptions = r.pendingOptions;
9435                    r.pendingOptions = null;
9436                    return activityOptions;
9437                }
9438                return null;
9439            }
9440        } finally {
9441            Binder.restoreCallingIdentity(origId);
9442        }
9443    }
9444
9445    @Override
9446    public void setImmersive(IBinder token, boolean immersive) {
9447        synchronized(this) {
9448            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9449            if (r == null) {
9450                throw new IllegalArgumentException();
9451            }
9452            r.immersive = immersive;
9453
9454            // update associated state if we're frontmost
9455            if (r == mFocusedActivity) {
9456                if (DEBUG_IMMERSIVE) {
9457                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9458                }
9459                applyUpdateLockStateLocked(r);
9460            }
9461        }
9462    }
9463
9464    @Override
9465    public boolean isImmersive(IBinder token) {
9466        synchronized (this) {
9467            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9468            if (r == null) {
9469                throw new IllegalArgumentException();
9470            }
9471            return r.immersive;
9472        }
9473    }
9474
9475    public boolean isTopActivityImmersive() {
9476        enforceNotIsolatedCaller("startActivity");
9477        synchronized (this) {
9478            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9479            return (r != null) ? r.immersive : false;
9480        }
9481    }
9482
9483    @Override
9484    public boolean isTopOfTask(IBinder token) {
9485        synchronized (this) {
9486            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9487            if (r == null) {
9488                throw new IllegalArgumentException();
9489            }
9490            return r.task.getTopActivity() == r;
9491        }
9492    }
9493
9494    public final void enterSafeMode() {
9495        synchronized(this) {
9496            // It only makes sense to do this before the system is ready
9497            // and started launching other packages.
9498            if (!mSystemReady) {
9499                try {
9500                    AppGlobals.getPackageManager().enterSafeMode();
9501                } catch (RemoteException e) {
9502                }
9503            }
9504
9505            mSafeMode = true;
9506        }
9507    }
9508
9509    public final void showSafeModeOverlay() {
9510        View v = LayoutInflater.from(mContext).inflate(
9511                com.android.internal.R.layout.safe_mode, null);
9512        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9513        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9514        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9515        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9516        lp.gravity = Gravity.BOTTOM | Gravity.START;
9517        lp.format = v.getBackground().getOpacity();
9518        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9519                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9520        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9521        ((WindowManager)mContext.getSystemService(
9522                Context.WINDOW_SERVICE)).addView(v, lp);
9523    }
9524
9525    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9526        if (!(sender instanceof PendingIntentRecord)) {
9527            return;
9528        }
9529        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9530        synchronized (stats) {
9531            if (mBatteryStatsService.isOnBattery()) {
9532                mBatteryStatsService.enforceCallingPermission();
9533                PendingIntentRecord rec = (PendingIntentRecord)sender;
9534                int MY_UID = Binder.getCallingUid();
9535                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9536                BatteryStatsImpl.Uid.Pkg pkg =
9537                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9538                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9539                pkg.incWakeupsLocked();
9540            }
9541        }
9542    }
9543
9544    public boolean killPids(int[] pids, String pReason, boolean secure) {
9545        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9546            throw new SecurityException("killPids only available to the system");
9547        }
9548        String reason = (pReason == null) ? "Unknown" : pReason;
9549        // XXX Note: don't acquire main activity lock here, because the window
9550        // manager calls in with its locks held.
9551
9552        boolean killed = false;
9553        synchronized (mPidsSelfLocked) {
9554            int[] types = new int[pids.length];
9555            int worstType = 0;
9556            for (int i=0; i<pids.length; i++) {
9557                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9558                if (proc != null) {
9559                    int type = proc.setAdj;
9560                    types[i] = type;
9561                    if (type > worstType) {
9562                        worstType = type;
9563                    }
9564                }
9565            }
9566
9567            // If the worst oom_adj is somewhere in the cached proc LRU range,
9568            // then constrain it so we will kill all cached procs.
9569            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9570                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9571                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9572            }
9573
9574            // If this is not a secure call, don't let it kill processes that
9575            // are important.
9576            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9577                worstType = ProcessList.SERVICE_ADJ;
9578            }
9579
9580            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9581            for (int i=0; i<pids.length; i++) {
9582                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9583                if (proc == null) {
9584                    continue;
9585                }
9586                int adj = proc.setAdj;
9587                if (adj >= worstType && !proc.killedByAm) {
9588                    killUnneededProcessLocked(proc, reason);
9589                    killed = true;
9590                }
9591            }
9592        }
9593        return killed;
9594    }
9595
9596    @Override
9597    public void killUid(int uid, String reason) {
9598        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9599            throw new SecurityException("killUid only available to the system");
9600        }
9601        synchronized (this) {
9602            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9603                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9604                    reason != null ? reason : "kill uid");
9605        }
9606    }
9607
9608    @Override
9609    public boolean killProcessesBelowForeground(String reason) {
9610        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9611            throw new SecurityException("killProcessesBelowForeground() only available to system");
9612        }
9613
9614        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9615    }
9616
9617    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9618        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9619            throw new SecurityException("killProcessesBelowAdj() only available to system");
9620        }
9621
9622        boolean killed = false;
9623        synchronized (mPidsSelfLocked) {
9624            final int size = mPidsSelfLocked.size();
9625            for (int i = 0; i < size; i++) {
9626                final int pid = mPidsSelfLocked.keyAt(i);
9627                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9628                if (proc == null) continue;
9629
9630                final int adj = proc.setAdj;
9631                if (adj > belowAdj && !proc.killedByAm) {
9632                    killUnneededProcessLocked(proc, reason);
9633                    killed = true;
9634                }
9635            }
9636        }
9637        return killed;
9638    }
9639
9640    @Override
9641    public void hang(final IBinder who, boolean allowRestart) {
9642        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9643                != PackageManager.PERMISSION_GRANTED) {
9644            throw new SecurityException("Requires permission "
9645                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9646        }
9647
9648        final IBinder.DeathRecipient death = new DeathRecipient() {
9649            @Override
9650            public void binderDied() {
9651                synchronized (this) {
9652                    notifyAll();
9653                }
9654            }
9655        };
9656
9657        try {
9658            who.linkToDeath(death, 0);
9659        } catch (RemoteException e) {
9660            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9661            return;
9662        }
9663
9664        synchronized (this) {
9665            Watchdog.getInstance().setAllowRestart(allowRestart);
9666            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9667            synchronized (death) {
9668                while (who.isBinderAlive()) {
9669                    try {
9670                        death.wait();
9671                    } catch (InterruptedException e) {
9672                    }
9673                }
9674            }
9675            Watchdog.getInstance().setAllowRestart(true);
9676        }
9677    }
9678
9679    @Override
9680    public void restart() {
9681        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9682                != PackageManager.PERMISSION_GRANTED) {
9683            throw new SecurityException("Requires permission "
9684                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9685        }
9686
9687        Log.i(TAG, "Sending shutdown broadcast...");
9688
9689        BroadcastReceiver br = new BroadcastReceiver() {
9690            @Override public void onReceive(Context context, Intent intent) {
9691                // Now the broadcast is done, finish up the low-level shutdown.
9692                Log.i(TAG, "Shutting down activity manager...");
9693                shutdown(10000);
9694                Log.i(TAG, "Shutdown complete, restarting!");
9695                Process.killProcess(Process.myPid());
9696                System.exit(10);
9697            }
9698        };
9699
9700        // First send the high-level shut down broadcast.
9701        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9702        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9703        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9704        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9705        mContext.sendOrderedBroadcastAsUser(intent,
9706                UserHandle.ALL, null, br, mHandler, 0, null, null);
9707        */
9708        br.onReceive(mContext, intent);
9709    }
9710
9711    private long getLowRamTimeSinceIdle(long now) {
9712        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9713    }
9714
9715    @Override
9716    public void performIdleMaintenance() {
9717        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9718                != PackageManager.PERMISSION_GRANTED) {
9719            throw new SecurityException("Requires permission "
9720                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9721        }
9722
9723        synchronized (this) {
9724            final long now = SystemClock.uptimeMillis();
9725            final long timeSinceLastIdle = now - mLastIdleTime;
9726            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9727            mLastIdleTime = now;
9728            mLowRamTimeSinceLastIdle = 0;
9729            if (mLowRamStartTime != 0) {
9730                mLowRamStartTime = now;
9731            }
9732
9733            StringBuilder sb = new StringBuilder(128);
9734            sb.append("Idle maintenance over ");
9735            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9736            sb.append(" low RAM for ");
9737            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9738            Slog.i(TAG, sb.toString());
9739
9740            // If at least 1/3 of our time since the last idle period has been spent
9741            // with RAM low, then we want to kill processes.
9742            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9743
9744            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9745                ProcessRecord proc = mLruProcesses.get(i);
9746                if (proc.notCachedSinceIdle) {
9747                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9748                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9749                        if (doKilling && proc.initialIdlePss != 0
9750                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9751                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9752                                    + " from " + proc.initialIdlePss + ")");
9753                        }
9754                    }
9755                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9756                    proc.notCachedSinceIdle = true;
9757                    proc.initialIdlePss = 0;
9758                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9759                            isSleeping(), now);
9760                }
9761            }
9762
9763            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9764            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9765        }
9766    }
9767
9768    private void retrieveSettings() {
9769        final ContentResolver resolver = mContext.getContentResolver();
9770        String debugApp = Settings.Global.getString(
9771            resolver, Settings.Global.DEBUG_APP);
9772        boolean waitForDebugger = Settings.Global.getInt(
9773            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9774        boolean alwaysFinishActivities = Settings.Global.getInt(
9775            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9776        boolean forceRtl = Settings.Global.getInt(
9777                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9778        // Transfer any global setting for forcing RTL layout, into a System Property
9779        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9780
9781        Configuration configuration = new Configuration();
9782        Settings.System.getConfiguration(resolver, configuration);
9783        if (forceRtl) {
9784            // This will take care of setting the correct layout direction flags
9785            configuration.setLayoutDirection(configuration.locale);
9786        }
9787
9788        synchronized (this) {
9789            mDebugApp = mOrigDebugApp = debugApp;
9790            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9791            mAlwaysFinishActivities = alwaysFinishActivities;
9792            // This happens before any activities are started, so we can
9793            // change mConfiguration in-place.
9794            updateConfigurationLocked(configuration, null, false, true);
9795            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9796        }
9797    }
9798
9799    public boolean testIsSystemReady() {
9800        // no need to synchronize(this) just to read & return the value
9801        return mSystemReady;
9802    }
9803
9804    private static File getCalledPreBootReceiversFile() {
9805        File dataDir = Environment.getDataDirectory();
9806        File systemDir = new File(dataDir, "system");
9807        File fname = new File(systemDir, "called_pre_boots.dat");
9808        return fname;
9809    }
9810
9811    static final int LAST_DONE_VERSION = 10000;
9812
9813    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9814        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9815        File file = getCalledPreBootReceiversFile();
9816        FileInputStream fis = null;
9817        try {
9818            fis = new FileInputStream(file);
9819            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9820            int fvers = dis.readInt();
9821            if (fvers == LAST_DONE_VERSION) {
9822                String vers = dis.readUTF();
9823                String codename = dis.readUTF();
9824                String build = dis.readUTF();
9825                if (android.os.Build.VERSION.RELEASE.equals(vers)
9826                        && android.os.Build.VERSION.CODENAME.equals(codename)
9827                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9828                    int num = dis.readInt();
9829                    while (num > 0) {
9830                        num--;
9831                        String pkg = dis.readUTF();
9832                        String cls = dis.readUTF();
9833                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9834                    }
9835                }
9836            }
9837        } catch (FileNotFoundException e) {
9838        } catch (IOException e) {
9839            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9840        } finally {
9841            if (fis != null) {
9842                try {
9843                    fis.close();
9844                } catch (IOException e) {
9845                }
9846            }
9847        }
9848        return lastDoneReceivers;
9849    }
9850
9851    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9852        File file = getCalledPreBootReceiversFile();
9853        FileOutputStream fos = null;
9854        DataOutputStream dos = null;
9855        try {
9856            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9857            fos = new FileOutputStream(file);
9858            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9859            dos.writeInt(LAST_DONE_VERSION);
9860            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9861            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9862            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9863            dos.writeInt(list.size());
9864            for (int i=0; i<list.size(); i++) {
9865                dos.writeUTF(list.get(i).getPackageName());
9866                dos.writeUTF(list.get(i).getClassName());
9867            }
9868        } catch (IOException e) {
9869            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9870            file.delete();
9871        } finally {
9872            FileUtils.sync(fos);
9873            if (dos != null) {
9874                try {
9875                    dos.close();
9876                } catch (IOException e) {
9877                    // TODO Auto-generated catch block
9878                    e.printStackTrace();
9879                }
9880            }
9881        }
9882    }
9883
9884    public void systemReady(final Runnable goingCallback) {
9885        synchronized(this) {
9886            if (mSystemReady) {
9887                if (goingCallback != null) goingCallback.run();
9888                return;
9889            }
9890
9891            if (mRecentTasks == null) {
9892                mRecentTasks = mTaskPersister.restoreTasksLocked();
9893                if (!mRecentTasks.isEmpty()) {
9894                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
9895                }
9896                mTaskPersister.startPersisting();
9897            }
9898
9899            // Check to see if there are any update receivers to run.
9900            if (!mDidUpdate) {
9901                if (mWaitingUpdate) {
9902                    return;
9903                }
9904                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9905                List<ResolveInfo> ris = null;
9906                try {
9907                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9908                            intent, null, 0, 0);
9909                } catch (RemoteException e) {
9910                }
9911                if (ris != null) {
9912                    for (int i=ris.size()-1; i>=0; i--) {
9913                        if ((ris.get(i).activityInfo.applicationInfo.flags
9914                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9915                            ris.remove(i);
9916                        }
9917                    }
9918                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9919
9920                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9921
9922                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9923                    for (int i=0; i<ris.size(); i++) {
9924                        ActivityInfo ai = ris.get(i).activityInfo;
9925                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9926                        if (lastDoneReceivers.contains(comp)) {
9927                            // We already did the pre boot receiver for this app with the current
9928                            // platform version, so don't do it again...
9929                            ris.remove(i);
9930                            i--;
9931                            // ...however, do keep it as one that has been done, so we don't
9932                            // forget about it when rewriting the file of last done receivers.
9933                            doneReceivers.add(comp);
9934                        }
9935                    }
9936
9937                    final int[] users = getUsersLocked();
9938                    for (int i=0; i<ris.size(); i++) {
9939                        ActivityInfo ai = ris.get(i).activityInfo;
9940                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9941                        doneReceivers.add(comp);
9942                        intent.setComponent(comp);
9943                        for (int j=0; j<users.length; j++) {
9944                            IIntentReceiver finisher = null;
9945                            if (i == ris.size()-1 && j == users.length-1) {
9946                                finisher = new IIntentReceiver.Stub() {
9947                                    public void performReceive(Intent intent, int resultCode,
9948                                            String data, Bundle extras, boolean ordered,
9949                                            boolean sticky, int sendingUser) {
9950                                        // The raw IIntentReceiver interface is called
9951                                        // with the AM lock held, so redispatch to
9952                                        // execute our code without the lock.
9953                                        mHandler.post(new Runnable() {
9954                                            public void run() {
9955                                                synchronized (ActivityManagerService.this) {
9956                                                    mDidUpdate = true;
9957                                                }
9958                                                writeLastDonePreBootReceivers(doneReceivers);
9959                                                showBootMessage(mContext.getText(
9960                                                        R.string.android_upgrading_complete),
9961                                                        false);
9962                                                systemReady(goingCallback);
9963                                            }
9964                                        });
9965                                    }
9966                                };
9967                            }
9968                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9969                                    + " for user " + users[j]);
9970                            broadcastIntentLocked(null, null, intent, null, finisher,
9971                                    0, null, null, null, AppOpsManager.OP_NONE,
9972                                    true, false, MY_PID, Process.SYSTEM_UID,
9973                                    users[j]);
9974                            if (finisher != null) {
9975                                mWaitingUpdate = true;
9976                            }
9977                        }
9978                    }
9979                }
9980                if (mWaitingUpdate) {
9981                    return;
9982                }
9983                mDidUpdate = true;
9984            }
9985
9986            mAppOpsService.systemReady();
9987            mUsageStatsService.systemReady();
9988            mSystemReady = true;
9989        }
9990
9991        ArrayList<ProcessRecord> procsToKill = null;
9992        synchronized(mPidsSelfLocked) {
9993            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9994                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9995                if (!isAllowedWhileBooting(proc.info)){
9996                    if (procsToKill == null) {
9997                        procsToKill = new ArrayList<ProcessRecord>();
9998                    }
9999                    procsToKill.add(proc);
10000                }
10001            }
10002        }
10003
10004        synchronized(this) {
10005            if (procsToKill != null) {
10006                for (int i=procsToKill.size()-1; i>=0; i--) {
10007                    ProcessRecord proc = procsToKill.get(i);
10008                    Slog.i(TAG, "Removing system update proc: " + proc);
10009                    removeProcessLocked(proc, true, false, "system update done");
10010                }
10011            }
10012
10013            // Now that we have cleaned up any update processes, we
10014            // are ready to start launching real processes and know that
10015            // we won't trample on them any more.
10016            mProcessesReady = true;
10017        }
10018
10019        Slog.i(TAG, "System now ready");
10020        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10021            SystemClock.uptimeMillis());
10022
10023        synchronized(this) {
10024            // Make sure we have no pre-ready processes sitting around.
10025
10026            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10027                ResolveInfo ri = mContext.getPackageManager()
10028                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10029                                STOCK_PM_FLAGS);
10030                CharSequence errorMsg = null;
10031                if (ri != null) {
10032                    ActivityInfo ai = ri.activityInfo;
10033                    ApplicationInfo app = ai.applicationInfo;
10034                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10035                        mTopAction = Intent.ACTION_FACTORY_TEST;
10036                        mTopData = null;
10037                        mTopComponent = new ComponentName(app.packageName,
10038                                ai.name);
10039                    } else {
10040                        errorMsg = mContext.getResources().getText(
10041                                com.android.internal.R.string.factorytest_not_system);
10042                    }
10043                } else {
10044                    errorMsg = mContext.getResources().getText(
10045                            com.android.internal.R.string.factorytest_no_action);
10046                }
10047                if (errorMsg != null) {
10048                    mTopAction = null;
10049                    mTopData = null;
10050                    mTopComponent = null;
10051                    Message msg = Message.obtain();
10052                    msg.what = SHOW_FACTORY_ERROR_MSG;
10053                    msg.getData().putCharSequence("msg", errorMsg);
10054                    mHandler.sendMessage(msg);
10055                }
10056            }
10057        }
10058
10059        retrieveSettings();
10060
10061        synchronized (this) {
10062            readGrantedUriPermissionsLocked();
10063        }
10064
10065        if (goingCallback != null) goingCallback.run();
10066
10067        mSystemServiceManager.startUser(mCurrentUserId);
10068
10069        synchronized (this) {
10070            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10071                try {
10072                    List apps = AppGlobals.getPackageManager().
10073                        getPersistentApplications(STOCK_PM_FLAGS);
10074                    if (apps != null) {
10075                        int N = apps.size();
10076                        int i;
10077                        for (i=0; i<N; i++) {
10078                            ApplicationInfo info
10079                                = (ApplicationInfo)apps.get(i);
10080                            if (info != null &&
10081                                    !info.packageName.equals("android")) {
10082                                addAppLocked(info, false, null /* ABI override */);
10083                            }
10084                        }
10085                    }
10086                } catch (RemoteException ex) {
10087                    // pm is in same process, this will never happen.
10088                }
10089            }
10090
10091            // Start up initial activity.
10092            mBooting = true;
10093
10094            try {
10095                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10096                    Message msg = Message.obtain();
10097                    msg.what = SHOW_UID_ERROR_MSG;
10098                    mHandler.sendMessage(msg);
10099                }
10100            } catch (RemoteException e) {
10101            }
10102
10103            long ident = Binder.clearCallingIdentity();
10104            try {
10105                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10106                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10107                        | Intent.FLAG_RECEIVER_FOREGROUND);
10108                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10109                broadcastIntentLocked(null, null, intent,
10110                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10111                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10112                intent = new Intent(Intent.ACTION_USER_STARTING);
10113                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10114                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10115                broadcastIntentLocked(null, null, intent,
10116                        null, new IIntentReceiver.Stub() {
10117                            @Override
10118                            public void performReceive(Intent intent, int resultCode, String data,
10119                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10120                                    throws RemoteException {
10121                            }
10122                        }, 0, null, null,
10123                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10124                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10125            } catch (Throwable t) {
10126                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10127            } finally {
10128                Binder.restoreCallingIdentity(ident);
10129            }
10130            mStackSupervisor.resumeTopActivitiesLocked();
10131            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10132        }
10133    }
10134
10135    private boolean makeAppCrashingLocked(ProcessRecord app,
10136            String shortMsg, String longMsg, String stackTrace) {
10137        app.crashing = true;
10138        app.crashingReport = generateProcessError(app,
10139                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10140        startAppProblemLocked(app);
10141        app.stopFreezingAllLocked();
10142        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10143    }
10144
10145    private void makeAppNotRespondingLocked(ProcessRecord app,
10146            String activity, String shortMsg, String longMsg) {
10147        app.notResponding = true;
10148        app.notRespondingReport = generateProcessError(app,
10149                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10150                activity, shortMsg, longMsg, null);
10151        startAppProblemLocked(app);
10152        app.stopFreezingAllLocked();
10153    }
10154
10155    /**
10156     * Generate a process error record, suitable for attachment to a ProcessRecord.
10157     *
10158     * @param app The ProcessRecord in which the error occurred.
10159     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10160     *                      ActivityManager.AppErrorStateInfo
10161     * @param activity The activity associated with the crash, if known.
10162     * @param shortMsg Short message describing the crash.
10163     * @param longMsg Long message describing the crash.
10164     * @param stackTrace Full crash stack trace, may be null.
10165     *
10166     * @return Returns a fully-formed AppErrorStateInfo record.
10167     */
10168    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10169            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10170        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10171
10172        report.condition = condition;
10173        report.processName = app.processName;
10174        report.pid = app.pid;
10175        report.uid = app.info.uid;
10176        report.tag = activity;
10177        report.shortMsg = shortMsg;
10178        report.longMsg = longMsg;
10179        report.stackTrace = stackTrace;
10180
10181        return report;
10182    }
10183
10184    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10185        synchronized (this) {
10186            app.crashing = false;
10187            app.crashingReport = null;
10188            app.notResponding = false;
10189            app.notRespondingReport = null;
10190            if (app.anrDialog == fromDialog) {
10191                app.anrDialog = null;
10192            }
10193            if (app.waitDialog == fromDialog) {
10194                app.waitDialog = null;
10195            }
10196            if (app.pid > 0 && app.pid != MY_PID) {
10197                handleAppCrashLocked(app, null, null, null);
10198                killUnneededProcessLocked(app, "user request after error");
10199            }
10200        }
10201    }
10202
10203    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10204            String stackTrace) {
10205        long now = SystemClock.uptimeMillis();
10206
10207        Long crashTime;
10208        if (!app.isolated) {
10209            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10210        } else {
10211            crashTime = null;
10212        }
10213        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10214            // This process loses!
10215            Slog.w(TAG, "Process " + app.info.processName
10216                    + " has crashed too many times: killing!");
10217            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10218                    app.userId, app.info.processName, app.uid);
10219            mStackSupervisor.handleAppCrashLocked(app);
10220            if (!app.persistent) {
10221                // We don't want to start this process again until the user
10222                // explicitly does so...  but for persistent process, we really
10223                // need to keep it running.  If a persistent process is actually
10224                // repeatedly crashing, then badness for everyone.
10225                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10226                        app.info.processName);
10227                if (!app.isolated) {
10228                    // XXX We don't have a way to mark isolated processes
10229                    // as bad, since they don't have a peristent identity.
10230                    mBadProcesses.put(app.info.processName, app.uid,
10231                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10232                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10233                }
10234                app.bad = true;
10235                app.removed = true;
10236                // Don't let services in this process be restarted and potentially
10237                // annoy the user repeatedly.  Unless it is persistent, since those
10238                // processes run critical code.
10239                removeProcessLocked(app, false, false, "crash");
10240                mStackSupervisor.resumeTopActivitiesLocked();
10241                return false;
10242            }
10243            mStackSupervisor.resumeTopActivitiesLocked();
10244        } else {
10245            mStackSupervisor.finishTopRunningActivityLocked(app);
10246        }
10247
10248        // Bump up the crash count of any services currently running in the proc.
10249        for (int i=app.services.size()-1; i>=0; i--) {
10250            // Any services running in the application need to be placed
10251            // back in the pending list.
10252            ServiceRecord sr = app.services.valueAt(i);
10253            sr.crashCount++;
10254        }
10255
10256        // If the crashing process is what we consider to be the "home process" and it has been
10257        // replaced by a third-party app, clear the package preferred activities from packages
10258        // with a home activity running in the process to prevent a repeatedly crashing app
10259        // from blocking the user to manually clear the list.
10260        final ArrayList<ActivityRecord> activities = app.activities;
10261        if (app == mHomeProcess && activities.size() > 0
10262                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10263            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10264                final ActivityRecord r = activities.get(activityNdx);
10265                if (r.isHomeActivity()) {
10266                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10267                    try {
10268                        ActivityThread.getPackageManager()
10269                                .clearPackagePreferredActivities(r.packageName);
10270                    } catch (RemoteException c) {
10271                        // pm is in same process, this will never happen.
10272                    }
10273                }
10274            }
10275        }
10276
10277        if (!app.isolated) {
10278            // XXX Can't keep track of crash times for isolated processes,
10279            // because they don't have a perisistent identity.
10280            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10281        }
10282
10283        return true;
10284    }
10285
10286    void startAppProblemLocked(ProcessRecord app) {
10287        if (app.userId == mCurrentUserId) {
10288            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10289                    mContext, app.info.packageName, app.info.flags);
10290        } else {
10291            // If this app is not running under the current user, then we
10292            // can't give it a report button because that would require
10293            // launching the report UI under a different user.
10294            app.errorReportReceiver = null;
10295        }
10296        skipCurrentReceiverLocked(app);
10297    }
10298
10299    void skipCurrentReceiverLocked(ProcessRecord app) {
10300        for (BroadcastQueue queue : mBroadcastQueues) {
10301            queue.skipCurrentReceiverLocked(app);
10302        }
10303    }
10304
10305    /**
10306     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10307     * The application process will exit immediately after this call returns.
10308     * @param app object of the crashing app, null for the system server
10309     * @param crashInfo describing the exception
10310     */
10311    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10312        ProcessRecord r = findAppProcess(app, "Crash");
10313        final String processName = app == null ? "system_server"
10314                : (r == null ? "unknown" : r.processName);
10315
10316        handleApplicationCrashInner("crash", r, processName, crashInfo);
10317    }
10318
10319    /* Native crash reporting uses this inner version because it needs to be somewhat
10320     * decoupled from the AM-managed cleanup lifecycle
10321     */
10322    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10323            ApplicationErrorReport.CrashInfo crashInfo) {
10324        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10325                UserHandle.getUserId(Binder.getCallingUid()), processName,
10326                r == null ? -1 : r.info.flags,
10327                crashInfo.exceptionClassName,
10328                crashInfo.exceptionMessage,
10329                crashInfo.throwFileName,
10330                crashInfo.throwLineNumber);
10331
10332        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10333
10334        crashApplication(r, crashInfo);
10335    }
10336
10337    public void handleApplicationStrictModeViolation(
10338            IBinder app,
10339            int violationMask,
10340            StrictMode.ViolationInfo info) {
10341        ProcessRecord r = findAppProcess(app, "StrictMode");
10342        if (r == null) {
10343            return;
10344        }
10345
10346        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10347            Integer stackFingerprint = info.hashCode();
10348            boolean logIt = true;
10349            synchronized (mAlreadyLoggedViolatedStacks) {
10350                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10351                    logIt = false;
10352                    // TODO: sub-sample into EventLog for these, with
10353                    // the info.durationMillis?  Then we'd get
10354                    // the relative pain numbers, without logging all
10355                    // the stack traces repeatedly.  We'd want to do
10356                    // likewise in the client code, which also does
10357                    // dup suppression, before the Binder call.
10358                } else {
10359                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10360                        mAlreadyLoggedViolatedStacks.clear();
10361                    }
10362                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10363                }
10364            }
10365            if (logIt) {
10366                logStrictModeViolationToDropBox(r, info);
10367            }
10368        }
10369
10370        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10371            AppErrorResult result = new AppErrorResult();
10372            synchronized (this) {
10373                final long origId = Binder.clearCallingIdentity();
10374
10375                Message msg = Message.obtain();
10376                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10377                HashMap<String, Object> data = new HashMap<String, Object>();
10378                data.put("result", result);
10379                data.put("app", r);
10380                data.put("violationMask", violationMask);
10381                data.put("info", info);
10382                msg.obj = data;
10383                mHandler.sendMessage(msg);
10384
10385                Binder.restoreCallingIdentity(origId);
10386            }
10387            int res = result.get();
10388            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10389        }
10390    }
10391
10392    // Depending on the policy in effect, there could be a bunch of
10393    // these in quick succession so we try to batch these together to
10394    // minimize disk writes, number of dropbox entries, and maximize
10395    // compression, by having more fewer, larger records.
10396    private void logStrictModeViolationToDropBox(
10397            ProcessRecord process,
10398            StrictMode.ViolationInfo info) {
10399        if (info == null) {
10400            return;
10401        }
10402        final boolean isSystemApp = process == null ||
10403                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10404                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10405        final String processName = process == null ? "unknown" : process.processName;
10406        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10407        final DropBoxManager dbox = (DropBoxManager)
10408                mContext.getSystemService(Context.DROPBOX_SERVICE);
10409
10410        // Exit early if the dropbox isn't configured to accept this report type.
10411        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10412
10413        boolean bufferWasEmpty;
10414        boolean needsFlush;
10415        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10416        synchronized (sb) {
10417            bufferWasEmpty = sb.length() == 0;
10418            appendDropBoxProcessHeaders(process, processName, sb);
10419            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10420            sb.append("System-App: ").append(isSystemApp).append("\n");
10421            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10422            if (info.violationNumThisLoop != 0) {
10423                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10424            }
10425            if (info.numAnimationsRunning != 0) {
10426                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10427            }
10428            if (info.broadcastIntentAction != null) {
10429                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10430            }
10431            if (info.durationMillis != -1) {
10432                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10433            }
10434            if (info.numInstances != -1) {
10435                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10436            }
10437            if (info.tags != null) {
10438                for (String tag : info.tags) {
10439                    sb.append("Span-Tag: ").append(tag).append("\n");
10440                }
10441            }
10442            sb.append("\n");
10443            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10444                sb.append(info.crashInfo.stackTrace);
10445            }
10446            sb.append("\n");
10447
10448            // Only buffer up to ~64k.  Various logging bits truncate
10449            // things at 128k.
10450            needsFlush = (sb.length() > 64 * 1024);
10451        }
10452
10453        // Flush immediately if the buffer's grown too large, or this
10454        // is a non-system app.  Non-system apps are isolated with a
10455        // different tag & policy and not batched.
10456        //
10457        // Batching is useful during internal testing with
10458        // StrictMode settings turned up high.  Without batching,
10459        // thousands of separate files could be created on boot.
10460        if (!isSystemApp || needsFlush) {
10461            new Thread("Error dump: " + dropboxTag) {
10462                @Override
10463                public void run() {
10464                    String report;
10465                    synchronized (sb) {
10466                        report = sb.toString();
10467                        sb.delete(0, sb.length());
10468                        sb.trimToSize();
10469                    }
10470                    if (report.length() != 0) {
10471                        dbox.addText(dropboxTag, report);
10472                    }
10473                }
10474            }.start();
10475            return;
10476        }
10477
10478        // System app batching:
10479        if (!bufferWasEmpty) {
10480            // An existing dropbox-writing thread is outstanding, so
10481            // we don't need to start it up.  The existing thread will
10482            // catch the buffer appends we just did.
10483            return;
10484        }
10485
10486        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10487        // (After this point, we shouldn't access AMS internal data structures.)
10488        new Thread("Error dump: " + dropboxTag) {
10489            @Override
10490            public void run() {
10491                // 5 second sleep to let stacks arrive and be batched together
10492                try {
10493                    Thread.sleep(5000);  // 5 seconds
10494                } catch (InterruptedException e) {}
10495
10496                String errorReport;
10497                synchronized (mStrictModeBuffer) {
10498                    errorReport = mStrictModeBuffer.toString();
10499                    if (errorReport.length() == 0) {
10500                        return;
10501                    }
10502                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10503                    mStrictModeBuffer.trimToSize();
10504                }
10505                dbox.addText(dropboxTag, errorReport);
10506            }
10507        }.start();
10508    }
10509
10510    /**
10511     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10512     * @param app object of the crashing app, null for the system server
10513     * @param tag reported by the caller
10514     * @param crashInfo describing the context of the error
10515     * @return true if the process should exit immediately (WTF is fatal)
10516     */
10517    public boolean handleApplicationWtf(IBinder app, String tag,
10518            ApplicationErrorReport.CrashInfo crashInfo) {
10519        ProcessRecord r = findAppProcess(app, "WTF");
10520        final String processName = app == null ? "system_server"
10521                : (r == null ? "unknown" : r.processName);
10522
10523        EventLog.writeEvent(EventLogTags.AM_WTF,
10524                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10525                processName,
10526                r == null ? -1 : r.info.flags,
10527                tag, crashInfo.exceptionMessage);
10528
10529        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10530
10531        if (r != null && r.pid != Process.myPid() &&
10532                Settings.Global.getInt(mContext.getContentResolver(),
10533                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10534            crashApplication(r, crashInfo);
10535            return true;
10536        } else {
10537            return false;
10538        }
10539    }
10540
10541    /**
10542     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10543     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10544     */
10545    private ProcessRecord findAppProcess(IBinder app, String reason) {
10546        if (app == null) {
10547            return null;
10548        }
10549
10550        synchronized (this) {
10551            final int NP = mProcessNames.getMap().size();
10552            for (int ip=0; ip<NP; ip++) {
10553                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10554                final int NA = apps.size();
10555                for (int ia=0; ia<NA; ia++) {
10556                    ProcessRecord p = apps.valueAt(ia);
10557                    if (p.thread != null && p.thread.asBinder() == app) {
10558                        return p;
10559                    }
10560                }
10561            }
10562
10563            Slog.w(TAG, "Can't find mystery application for " + reason
10564                    + " from pid=" + Binder.getCallingPid()
10565                    + " uid=" + Binder.getCallingUid() + ": " + app);
10566            return null;
10567        }
10568    }
10569
10570    /**
10571     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10572     * to append various headers to the dropbox log text.
10573     */
10574    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10575            StringBuilder sb) {
10576        // Watchdog thread ends up invoking this function (with
10577        // a null ProcessRecord) to add the stack file to dropbox.
10578        // Do not acquire a lock on this (am) in such cases, as it
10579        // could cause a potential deadlock, if and when watchdog
10580        // is invoked due to unavailability of lock on am and it
10581        // would prevent watchdog from killing system_server.
10582        if (process == null) {
10583            sb.append("Process: ").append(processName).append("\n");
10584            return;
10585        }
10586        // Note: ProcessRecord 'process' is guarded by the service
10587        // instance.  (notably process.pkgList, which could otherwise change
10588        // concurrently during execution of this method)
10589        synchronized (this) {
10590            sb.append("Process: ").append(processName).append("\n");
10591            int flags = process.info.flags;
10592            IPackageManager pm = AppGlobals.getPackageManager();
10593            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10594            for (int ip=0; ip<process.pkgList.size(); ip++) {
10595                String pkg = process.pkgList.keyAt(ip);
10596                sb.append("Package: ").append(pkg);
10597                try {
10598                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10599                    if (pi != null) {
10600                        sb.append(" v").append(pi.versionCode);
10601                        if (pi.versionName != null) {
10602                            sb.append(" (").append(pi.versionName).append(")");
10603                        }
10604                    }
10605                } catch (RemoteException e) {
10606                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10607                }
10608                sb.append("\n");
10609            }
10610        }
10611    }
10612
10613    private static String processClass(ProcessRecord process) {
10614        if (process == null || process.pid == MY_PID) {
10615            return "system_server";
10616        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10617            return "system_app";
10618        } else {
10619            return "data_app";
10620        }
10621    }
10622
10623    /**
10624     * Write a description of an error (crash, WTF, ANR) to the drop box.
10625     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10626     * @param process which caused the error, null means the system server
10627     * @param activity which triggered the error, null if unknown
10628     * @param parent activity related to the error, null if unknown
10629     * @param subject line related to the error, null if absent
10630     * @param report in long form describing the error, null if absent
10631     * @param logFile to include in the report, null if none
10632     * @param crashInfo giving an application stack trace, null if absent
10633     */
10634    public void addErrorToDropBox(String eventType,
10635            ProcessRecord process, String processName, ActivityRecord activity,
10636            ActivityRecord parent, String subject,
10637            final String report, final File logFile,
10638            final ApplicationErrorReport.CrashInfo crashInfo) {
10639        // NOTE -- this must never acquire the ActivityManagerService lock,
10640        // otherwise the watchdog may be prevented from resetting the system.
10641
10642        final String dropboxTag = processClass(process) + "_" + eventType;
10643        final DropBoxManager dbox = (DropBoxManager)
10644                mContext.getSystemService(Context.DROPBOX_SERVICE);
10645
10646        // Exit early if the dropbox isn't configured to accept this report type.
10647        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10648
10649        final StringBuilder sb = new StringBuilder(1024);
10650        appendDropBoxProcessHeaders(process, processName, sb);
10651        if (activity != null) {
10652            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10653        }
10654        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10655            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10656        }
10657        if (parent != null && parent != activity) {
10658            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10659        }
10660        if (subject != null) {
10661            sb.append("Subject: ").append(subject).append("\n");
10662        }
10663        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10664        if (Debug.isDebuggerConnected()) {
10665            sb.append("Debugger: Connected\n");
10666        }
10667        sb.append("\n");
10668
10669        // Do the rest in a worker thread to avoid blocking the caller on I/O
10670        // (After this point, we shouldn't access AMS internal data structures.)
10671        Thread worker = new Thread("Error dump: " + dropboxTag) {
10672            @Override
10673            public void run() {
10674                if (report != null) {
10675                    sb.append(report);
10676                }
10677                if (logFile != null) {
10678                    try {
10679                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10680                                    "\n\n[[TRUNCATED]]"));
10681                    } catch (IOException e) {
10682                        Slog.e(TAG, "Error reading " + logFile, e);
10683                    }
10684                }
10685                if (crashInfo != null && crashInfo.stackTrace != null) {
10686                    sb.append(crashInfo.stackTrace);
10687                }
10688
10689                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10690                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10691                if (lines > 0) {
10692                    sb.append("\n");
10693
10694                    // Merge several logcat streams, and take the last N lines
10695                    InputStreamReader input = null;
10696                    try {
10697                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10698                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10699                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10700
10701                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10702                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10703                        input = new InputStreamReader(logcat.getInputStream());
10704
10705                        int num;
10706                        char[] buf = new char[8192];
10707                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10708                    } catch (IOException e) {
10709                        Slog.e(TAG, "Error running logcat", e);
10710                    } finally {
10711                        if (input != null) try { input.close(); } catch (IOException e) {}
10712                    }
10713                }
10714
10715                dbox.addText(dropboxTag, sb.toString());
10716            }
10717        };
10718
10719        if (process == null) {
10720            // If process is null, we are being called from some internal code
10721            // and may be about to die -- run this synchronously.
10722            worker.run();
10723        } else {
10724            worker.start();
10725        }
10726    }
10727
10728    /**
10729     * Bring up the "unexpected error" dialog box for a crashing app.
10730     * Deal with edge cases (intercepts from instrumented applications,
10731     * ActivityController, error intent receivers, that sort of thing).
10732     * @param r the application crashing
10733     * @param crashInfo describing the failure
10734     */
10735    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10736        long timeMillis = System.currentTimeMillis();
10737        String shortMsg = crashInfo.exceptionClassName;
10738        String longMsg = crashInfo.exceptionMessage;
10739        String stackTrace = crashInfo.stackTrace;
10740        if (shortMsg != null && longMsg != null) {
10741            longMsg = shortMsg + ": " + longMsg;
10742        } else if (shortMsg != null) {
10743            longMsg = shortMsg;
10744        }
10745
10746        AppErrorResult result = new AppErrorResult();
10747        synchronized (this) {
10748            if (mController != null) {
10749                try {
10750                    String name = r != null ? r.processName : null;
10751                    int pid = r != null ? r.pid : Binder.getCallingPid();
10752                    if (!mController.appCrashed(name, pid,
10753                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10754                        Slog.w(TAG, "Force-killing crashed app " + name
10755                                + " at watcher's request");
10756                        Process.killProcess(pid);
10757                        return;
10758                    }
10759                } catch (RemoteException e) {
10760                    mController = null;
10761                    Watchdog.getInstance().setActivityController(null);
10762                }
10763            }
10764
10765            final long origId = Binder.clearCallingIdentity();
10766
10767            // If this process is running instrumentation, finish it.
10768            if (r != null && r.instrumentationClass != null) {
10769                Slog.w(TAG, "Error in app " + r.processName
10770                      + " running instrumentation " + r.instrumentationClass + ":");
10771                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10772                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10773                Bundle info = new Bundle();
10774                info.putString("shortMsg", shortMsg);
10775                info.putString("longMsg", longMsg);
10776                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10777                Binder.restoreCallingIdentity(origId);
10778                return;
10779            }
10780
10781            // If we can't identify the process or it's already exceeded its crash quota,
10782            // quit right away without showing a crash dialog.
10783            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10784                Binder.restoreCallingIdentity(origId);
10785                return;
10786            }
10787
10788            Message msg = Message.obtain();
10789            msg.what = SHOW_ERROR_MSG;
10790            HashMap data = new HashMap();
10791            data.put("result", result);
10792            data.put("app", r);
10793            msg.obj = data;
10794            mHandler.sendMessage(msg);
10795
10796            Binder.restoreCallingIdentity(origId);
10797        }
10798
10799        int res = result.get();
10800
10801        Intent appErrorIntent = null;
10802        synchronized (this) {
10803            if (r != null && !r.isolated) {
10804                // XXX Can't keep track of crash time for isolated processes,
10805                // since they don't have a persistent identity.
10806                mProcessCrashTimes.put(r.info.processName, r.uid,
10807                        SystemClock.uptimeMillis());
10808            }
10809            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10810                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10811            }
10812        }
10813
10814        if (appErrorIntent != null) {
10815            try {
10816                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10817            } catch (ActivityNotFoundException e) {
10818                Slog.w(TAG, "bug report receiver dissappeared", e);
10819            }
10820        }
10821    }
10822
10823    Intent createAppErrorIntentLocked(ProcessRecord r,
10824            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10825        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10826        if (report == null) {
10827            return null;
10828        }
10829        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10830        result.setComponent(r.errorReportReceiver);
10831        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10832        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10833        return result;
10834    }
10835
10836    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10837            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10838        if (r.errorReportReceiver == null) {
10839            return null;
10840        }
10841
10842        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10843            return null;
10844        }
10845
10846        ApplicationErrorReport report = new ApplicationErrorReport();
10847        report.packageName = r.info.packageName;
10848        report.installerPackageName = r.errorReportReceiver.getPackageName();
10849        report.processName = r.processName;
10850        report.time = timeMillis;
10851        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10852
10853        if (r.crashing || r.forceCrashReport) {
10854            report.type = ApplicationErrorReport.TYPE_CRASH;
10855            report.crashInfo = crashInfo;
10856        } else if (r.notResponding) {
10857            report.type = ApplicationErrorReport.TYPE_ANR;
10858            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10859
10860            report.anrInfo.activity = r.notRespondingReport.tag;
10861            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10862            report.anrInfo.info = r.notRespondingReport.longMsg;
10863        }
10864
10865        return report;
10866    }
10867
10868    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10869        enforceNotIsolatedCaller("getProcessesInErrorState");
10870        // assume our apps are happy - lazy create the list
10871        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10872
10873        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10874                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10875        int userId = UserHandle.getUserId(Binder.getCallingUid());
10876
10877        synchronized (this) {
10878
10879            // iterate across all processes
10880            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10881                ProcessRecord app = mLruProcesses.get(i);
10882                if (!allUsers && app.userId != userId) {
10883                    continue;
10884                }
10885                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10886                    // This one's in trouble, so we'll generate a report for it
10887                    // crashes are higher priority (in case there's a crash *and* an anr)
10888                    ActivityManager.ProcessErrorStateInfo report = null;
10889                    if (app.crashing) {
10890                        report = app.crashingReport;
10891                    } else if (app.notResponding) {
10892                        report = app.notRespondingReport;
10893                    }
10894
10895                    if (report != null) {
10896                        if (errList == null) {
10897                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10898                        }
10899                        errList.add(report);
10900                    } else {
10901                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10902                                " crashing = " + app.crashing +
10903                                " notResponding = " + app.notResponding);
10904                    }
10905                }
10906            }
10907        }
10908
10909        return errList;
10910    }
10911
10912    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10913        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10914            if (currApp != null) {
10915                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10916            }
10917            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10918        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10919            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10920        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10921            if (currApp != null) {
10922                currApp.lru = 0;
10923            }
10924            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10925        } else if (adj >= ProcessList.SERVICE_ADJ) {
10926            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10927        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10928            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10929        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10930            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10931        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10932            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10933        } else {
10934            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10935        }
10936    }
10937
10938    private void fillInProcMemInfo(ProcessRecord app,
10939            ActivityManager.RunningAppProcessInfo outInfo) {
10940        outInfo.pid = app.pid;
10941        outInfo.uid = app.info.uid;
10942        if (mHeavyWeightProcess == app) {
10943            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10944        }
10945        if (app.persistent) {
10946            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10947        }
10948        if (app.activities.size() > 0) {
10949            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10950        }
10951        outInfo.lastTrimLevel = app.trimMemoryLevel;
10952        int adj = app.curAdj;
10953        outInfo.importance = oomAdjToImportance(adj, outInfo);
10954        outInfo.importanceReasonCode = app.adjTypeCode;
10955        outInfo.processState = app.curProcState;
10956    }
10957
10958    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10959        enforceNotIsolatedCaller("getRunningAppProcesses");
10960        // Lazy instantiation of list
10961        List<ActivityManager.RunningAppProcessInfo> runList = null;
10962        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10963                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10964        int userId = UserHandle.getUserId(Binder.getCallingUid());
10965        synchronized (this) {
10966            // Iterate across all processes
10967            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10968                ProcessRecord app = mLruProcesses.get(i);
10969                if (!allUsers && app.userId != userId) {
10970                    continue;
10971                }
10972                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10973                    // Generate process state info for running application
10974                    ActivityManager.RunningAppProcessInfo currApp =
10975                        new ActivityManager.RunningAppProcessInfo(app.processName,
10976                                app.pid, app.getPackageList());
10977                    fillInProcMemInfo(app, currApp);
10978                    if (app.adjSource instanceof ProcessRecord) {
10979                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10980                        currApp.importanceReasonImportance = oomAdjToImportance(
10981                                app.adjSourceOom, null);
10982                    } else if (app.adjSource instanceof ActivityRecord) {
10983                        ActivityRecord r = (ActivityRecord)app.adjSource;
10984                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10985                    }
10986                    if (app.adjTarget instanceof ComponentName) {
10987                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10988                    }
10989                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10990                    //        + " lru=" + currApp.lru);
10991                    if (runList == null) {
10992                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10993                    }
10994                    runList.add(currApp);
10995                }
10996            }
10997        }
10998        return runList;
10999    }
11000
11001    public List<ApplicationInfo> getRunningExternalApplications() {
11002        enforceNotIsolatedCaller("getRunningExternalApplications");
11003        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11004        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11005        if (runningApps != null && runningApps.size() > 0) {
11006            Set<String> extList = new HashSet<String>();
11007            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11008                if (app.pkgList != null) {
11009                    for (String pkg : app.pkgList) {
11010                        extList.add(pkg);
11011                    }
11012                }
11013            }
11014            IPackageManager pm = AppGlobals.getPackageManager();
11015            for (String pkg : extList) {
11016                try {
11017                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11018                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11019                        retList.add(info);
11020                    }
11021                } catch (RemoteException e) {
11022                }
11023            }
11024        }
11025        return retList;
11026    }
11027
11028    @Override
11029    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
11030        enforceNotIsolatedCaller("getMyMemoryState");
11031        synchronized (this) {
11032            ProcessRecord proc;
11033            synchronized (mPidsSelfLocked) {
11034                proc = mPidsSelfLocked.get(Binder.getCallingPid());
11035            }
11036            fillInProcMemInfo(proc, outInfo);
11037        }
11038    }
11039
11040    @Override
11041    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11042        if (checkCallingPermission(android.Manifest.permission.DUMP)
11043                != PackageManager.PERMISSION_GRANTED) {
11044            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11045                    + Binder.getCallingPid()
11046                    + ", uid=" + Binder.getCallingUid()
11047                    + " without permission "
11048                    + android.Manifest.permission.DUMP);
11049            return;
11050        }
11051
11052        boolean dumpAll = false;
11053        boolean dumpClient = false;
11054        String dumpPackage = null;
11055
11056        int opti = 0;
11057        while (opti < args.length) {
11058            String opt = args[opti];
11059            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11060                break;
11061            }
11062            opti++;
11063            if ("-a".equals(opt)) {
11064                dumpAll = true;
11065            } else if ("-c".equals(opt)) {
11066                dumpClient = true;
11067            } else if ("-h".equals(opt)) {
11068                pw.println("Activity manager dump options:");
11069                pw.println("  [-a] [-c] [-h] [cmd] ...");
11070                pw.println("  cmd may be one of:");
11071                pw.println("    a[ctivities]: activity stack state");
11072                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11073                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11074                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11075                pw.println("    o[om]: out of memory management");
11076                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11077                pw.println("    provider [COMP_SPEC]: provider client-side state");
11078                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11079                pw.println("    service [COMP_SPEC]: service client-side state");
11080                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11081                pw.println("    all: dump all activities");
11082                pw.println("    top: dump the top activity");
11083                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11084                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11085                pw.println("    a partial substring in a component name, a");
11086                pw.println("    hex object identifier.");
11087                pw.println("  -a: include all available server state.");
11088                pw.println("  -c: include client state.");
11089                return;
11090            } else {
11091                pw.println("Unknown argument: " + opt + "; use -h for help");
11092            }
11093        }
11094
11095        long origId = Binder.clearCallingIdentity();
11096        boolean more = false;
11097        // Is the caller requesting to dump a particular piece of data?
11098        if (opti < args.length) {
11099            String cmd = args[opti];
11100            opti++;
11101            if ("activities".equals(cmd) || "a".equals(cmd)) {
11102                synchronized (this) {
11103                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11104                }
11105            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11106                String[] newArgs;
11107                String name;
11108                if (opti >= args.length) {
11109                    name = null;
11110                    newArgs = EMPTY_STRING_ARRAY;
11111                } else {
11112                    name = args[opti];
11113                    opti++;
11114                    newArgs = new String[args.length - opti];
11115                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11116                            args.length - opti);
11117                }
11118                synchronized (this) {
11119                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11120                }
11121            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11122                String[] newArgs;
11123                String name;
11124                if (opti >= args.length) {
11125                    name = null;
11126                    newArgs = EMPTY_STRING_ARRAY;
11127                } else {
11128                    name = args[opti];
11129                    opti++;
11130                    newArgs = new String[args.length - opti];
11131                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11132                            args.length - opti);
11133                }
11134                synchronized (this) {
11135                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11136                }
11137            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11138                String[] newArgs;
11139                String name;
11140                if (opti >= args.length) {
11141                    name = null;
11142                    newArgs = EMPTY_STRING_ARRAY;
11143                } else {
11144                    name = args[opti];
11145                    opti++;
11146                    newArgs = new String[args.length - opti];
11147                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11148                            args.length - opti);
11149                }
11150                synchronized (this) {
11151                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11152                }
11153            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11154                synchronized (this) {
11155                    dumpOomLocked(fd, pw, args, opti, true);
11156                }
11157            } else if ("provider".equals(cmd)) {
11158                String[] newArgs;
11159                String name;
11160                if (opti >= args.length) {
11161                    name = null;
11162                    newArgs = EMPTY_STRING_ARRAY;
11163                } else {
11164                    name = args[opti];
11165                    opti++;
11166                    newArgs = new String[args.length - opti];
11167                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11168                }
11169                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11170                    pw.println("No providers match: " + name);
11171                    pw.println("Use -h for help.");
11172                }
11173            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11174                synchronized (this) {
11175                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11176                }
11177            } else if ("service".equals(cmd)) {
11178                String[] newArgs;
11179                String name;
11180                if (opti >= args.length) {
11181                    name = null;
11182                    newArgs = EMPTY_STRING_ARRAY;
11183                } else {
11184                    name = args[opti];
11185                    opti++;
11186                    newArgs = new String[args.length - opti];
11187                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11188                            args.length - opti);
11189                }
11190                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11191                    pw.println("No services match: " + name);
11192                    pw.println("Use -h for help.");
11193                }
11194            } else if ("package".equals(cmd)) {
11195                String[] newArgs;
11196                if (opti >= args.length) {
11197                    pw.println("package: no package name specified");
11198                    pw.println("Use -h for help.");
11199                } else {
11200                    dumpPackage = args[opti];
11201                    opti++;
11202                    newArgs = new String[args.length - opti];
11203                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11204                            args.length - opti);
11205                    args = newArgs;
11206                    opti = 0;
11207                    more = true;
11208                }
11209            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11210                synchronized (this) {
11211                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11212                }
11213            } else {
11214                // Dumping a single activity?
11215                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11216                    pw.println("Bad activity command, or no activities match: " + cmd);
11217                    pw.println("Use -h for help.");
11218                }
11219            }
11220            if (!more) {
11221                Binder.restoreCallingIdentity(origId);
11222                return;
11223            }
11224        }
11225
11226        // No piece of data specified, dump everything.
11227        synchronized (this) {
11228            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11229            pw.println();
11230            if (dumpAll) {
11231                pw.println("-------------------------------------------------------------------------------");
11232            }
11233            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11234            pw.println();
11235            if (dumpAll) {
11236                pw.println("-------------------------------------------------------------------------------");
11237            }
11238            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11239            pw.println();
11240            if (dumpAll) {
11241                pw.println("-------------------------------------------------------------------------------");
11242            }
11243            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11244            pw.println();
11245            if (dumpAll) {
11246                pw.println("-------------------------------------------------------------------------------");
11247            }
11248            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11249            pw.println();
11250            if (dumpAll) {
11251                pw.println("-------------------------------------------------------------------------------");
11252            }
11253            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11254        }
11255        Binder.restoreCallingIdentity(origId);
11256    }
11257
11258    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11259            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11260        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11261
11262        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11263                dumpPackage);
11264        boolean needSep = printedAnything;
11265
11266        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11267                dumpPackage, needSep, "  mFocusedActivity: ");
11268        if (printed) {
11269            printedAnything = true;
11270            needSep = false;
11271        }
11272
11273        if (dumpPackage == null) {
11274            if (needSep) {
11275                pw.println();
11276            }
11277            needSep = true;
11278            printedAnything = true;
11279            mStackSupervisor.dump(pw, "  ");
11280        }
11281
11282        if (mRecentTasks.size() > 0) {
11283            boolean printedHeader = false;
11284
11285            final int N = mRecentTasks.size();
11286            for (int i=0; i<N; i++) {
11287                TaskRecord tr = mRecentTasks.get(i);
11288                if (dumpPackage != null) {
11289                    if (tr.realActivity == null ||
11290                            !dumpPackage.equals(tr.realActivity)) {
11291                        continue;
11292                    }
11293                }
11294                if (!printedHeader) {
11295                    if (needSep) {
11296                        pw.println();
11297                    }
11298                    pw.println("  Recent tasks:");
11299                    printedHeader = true;
11300                    printedAnything = true;
11301                }
11302                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11303                        pw.println(tr);
11304                if (dumpAll) {
11305                    mRecentTasks.get(i).dump(pw, "    ");
11306                }
11307            }
11308        }
11309
11310        if (!printedAnything) {
11311            pw.println("  (nothing)");
11312        }
11313    }
11314
11315    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11316            int opti, boolean dumpAll, String dumpPackage) {
11317        boolean needSep = false;
11318        boolean printedAnything = false;
11319        int numPers = 0;
11320
11321        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11322
11323        if (dumpAll) {
11324            final int NP = mProcessNames.getMap().size();
11325            for (int ip=0; ip<NP; ip++) {
11326                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11327                final int NA = procs.size();
11328                for (int ia=0; ia<NA; ia++) {
11329                    ProcessRecord r = procs.valueAt(ia);
11330                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11331                        continue;
11332                    }
11333                    if (!needSep) {
11334                        pw.println("  All known processes:");
11335                        needSep = true;
11336                        printedAnything = true;
11337                    }
11338                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11339                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11340                        pw.print(" "); pw.println(r);
11341                    r.dump(pw, "    ");
11342                    if (r.persistent) {
11343                        numPers++;
11344                    }
11345                }
11346            }
11347        }
11348
11349        if (mIsolatedProcesses.size() > 0) {
11350            boolean printed = false;
11351            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11352                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11353                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11354                    continue;
11355                }
11356                if (!printed) {
11357                    if (needSep) {
11358                        pw.println();
11359                    }
11360                    pw.println("  Isolated process list (sorted by uid):");
11361                    printedAnything = true;
11362                    printed = true;
11363                    needSep = true;
11364                }
11365                pw.println(String.format("%sIsolated #%2d: %s",
11366                        "    ", i, r.toString()));
11367            }
11368        }
11369
11370        if (mLruProcesses.size() > 0) {
11371            if (needSep) {
11372                pw.println();
11373            }
11374            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11375                    pw.print(" total, non-act at ");
11376                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11377                    pw.print(", non-svc at ");
11378                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11379                    pw.println("):");
11380            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11381            needSep = true;
11382            printedAnything = true;
11383        }
11384
11385        if (dumpAll || dumpPackage != null) {
11386            synchronized (mPidsSelfLocked) {
11387                boolean printed = false;
11388                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11389                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11390                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11391                        continue;
11392                    }
11393                    if (!printed) {
11394                        if (needSep) pw.println();
11395                        needSep = true;
11396                        pw.println("  PID mappings:");
11397                        printed = true;
11398                        printedAnything = true;
11399                    }
11400                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11401                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11402                }
11403            }
11404        }
11405
11406        if (mForegroundProcesses.size() > 0) {
11407            synchronized (mPidsSelfLocked) {
11408                boolean printed = false;
11409                for (int i=0; i<mForegroundProcesses.size(); i++) {
11410                    ProcessRecord r = mPidsSelfLocked.get(
11411                            mForegroundProcesses.valueAt(i).pid);
11412                    if (dumpPackage != null && (r == null
11413                            || !r.pkgList.containsKey(dumpPackage))) {
11414                        continue;
11415                    }
11416                    if (!printed) {
11417                        if (needSep) pw.println();
11418                        needSep = true;
11419                        pw.println("  Foreground Processes:");
11420                        printed = true;
11421                        printedAnything = true;
11422                    }
11423                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11424                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11425                }
11426            }
11427        }
11428
11429        if (mPersistentStartingProcesses.size() > 0) {
11430            if (needSep) pw.println();
11431            needSep = true;
11432            printedAnything = true;
11433            pw.println("  Persisent processes that are starting:");
11434            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11435                    "Starting Norm", "Restarting PERS", dumpPackage);
11436        }
11437
11438        if (mRemovedProcesses.size() > 0) {
11439            if (needSep) pw.println();
11440            needSep = true;
11441            printedAnything = true;
11442            pw.println("  Processes that are being removed:");
11443            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11444                    "Removed Norm", "Removed PERS", dumpPackage);
11445        }
11446
11447        if (mProcessesOnHold.size() > 0) {
11448            if (needSep) pw.println();
11449            needSep = true;
11450            printedAnything = true;
11451            pw.println("  Processes that are on old until the system is ready:");
11452            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11453                    "OnHold Norm", "OnHold PERS", dumpPackage);
11454        }
11455
11456        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11457
11458        if (mProcessCrashTimes.getMap().size() > 0) {
11459            boolean printed = false;
11460            long now = SystemClock.uptimeMillis();
11461            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11462            final int NP = pmap.size();
11463            for (int ip=0; ip<NP; ip++) {
11464                String pname = pmap.keyAt(ip);
11465                SparseArray<Long> uids = pmap.valueAt(ip);
11466                final int N = uids.size();
11467                for (int i=0; i<N; i++) {
11468                    int puid = uids.keyAt(i);
11469                    ProcessRecord r = mProcessNames.get(pname, puid);
11470                    if (dumpPackage != null && (r == null
11471                            || !r.pkgList.containsKey(dumpPackage))) {
11472                        continue;
11473                    }
11474                    if (!printed) {
11475                        if (needSep) pw.println();
11476                        needSep = true;
11477                        pw.println("  Time since processes crashed:");
11478                        printed = true;
11479                        printedAnything = true;
11480                    }
11481                    pw.print("    Process "); pw.print(pname);
11482                            pw.print(" uid "); pw.print(puid);
11483                            pw.print(": last crashed ");
11484                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11485                            pw.println(" ago");
11486                }
11487            }
11488        }
11489
11490        if (mBadProcesses.getMap().size() > 0) {
11491            boolean printed = false;
11492            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11493            final int NP = pmap.size();
11494            for (int ip=0; ip<NP; ip++) {
11495                String pname = pmap.keyAt(ip);
11496                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11497                final int N = uids.size();
11498                for (int i=0; i<N; i++) {
11499                    int puid = uids.keyAt(i);
11500                    ProcessRecord r = mProcessNames.get(pname, puid);
11501                    if (dumpPackage != null && (r == null
11502                            || !r.pkgList.containsKey(dumpPackage))) {
11503                        continue;
11504                    }
11505                    if (!printed) {
11506                        if (needSep) pw.println();
11507                        needSep = true;
11508                        pw.println("  Bad processes:");
11509                        printedAnything = true;
11510                    }
11511                    BadProcessInfo info = uids.valueAt(i);
11512                    pw.print("    Bad process "); pw.print(pname);
11513                            pw.print(" uid "); pw.print(puid);
11514                            pw.print(": crashed at time "); pw.println(info.time);
11515                    if (info.shortMsg != null) {
11516                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11517                    }
11518                    if (info.longMsg != null) {
11519                        pw.print("      Long msg: "); pw.println(info.longMsg);
11520                    }
11521                    if (info.stack != null) {
11522                        pw.println("      Stack:");
11523                        int lastPos = 0;
11524                        for (int pos=0; pos<info.stack.length(); pos++) {
11525                            if (info.stack.charAt(pos) == '\n') {
11526                                pw.print("        ");
11527                                pw.write(info.stack, lastPos, pos-lastPos);
11528                                pw.println();
11529                                lastPos = pos+1;
11530                            }
11531                        }
11532                        if (lastPos < info.stack.length()) {
11533                            pw.print("        ");
11534                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11535                            pw.println();
11536                        }
11537                    }
11538                }
11539            }
11540        }
11541
11542        if (dumpPackage == null) {
11543            pw.println();
11544            needSep = false;
11545            pw.println("  mStartedUsers:");
11546            for (int i=0; i<mStartedUsers.size(); i++) {
11547                UserStartedState uss = mStartedUsers.valueAt(i);
11548                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11549                        pw.print(": "); uss.dump("", pw);
11550            }
11551            pw.print("  mStartedUserArray: [");
11552            for (int i=0; i<mStartedUserArray.length; i++) {
11553                if (i > 0) pw.print(", ");
11554                pw.print(mStartedUserArray[i]);
11555            }
11556            pw.println("]");
11557            pw.print("  mUserLru: [");
11558            for (int i=0; i<mUserLru.size(); i++) {
11559                if (i > 0) pw.print(", ");
11560                pw.print(mUserLru.get(i));
11561            }
11562            pw.println("]");
11563            if (dumpAll) {
11564                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11565            }
11566        }
11567        if (mHomeProcess != null && (dumpPackage == null
11568                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11569            if (needSep) {
11570                pw.println();
11571                needSep = false;
11572            }
11573            pw.println("  mHomeProcess: " + mHomeProcess);
11574        }
11575        if (mPreviousProcess != null && (dumpPackage == null
11576                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11577            if (needSep) {
11578                pw.println();
11579                needSep = false;
11580            }
11581            pw.println("  mPreviousProcess: " + mPreviousProcess);
11582        }
11583        if (dumpAll) {
11584            StringBuilder sb = new StringBuilder(128);
11585            sb.append("  mPreviousProcessVisibleTime: ");
11586            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11587            pw.println(sb);
11588        }
11589        if (mHeavyWeightProcess != null && (dumpPackage == null
11590                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11591            if (needSep) {
11592                pw.println();
11593                needSep = false;
11594            }
11595            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11596        }
11597        if (dumpPackage == null) {
11598            pw.println("  mConfiguration: " + mConfiguration);
11599        }
11600        if (dumpAll) {
11601            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11602            if (mCompatModePackages.getPackages().size() > 0) {
11603                boolean printed = false;
11604                for (Map.Entry<String, Integer> entry
11605                        : mCompatModePackages.getPackages().entrySet()) {
11606                    String pkg = entry.getKey();
11607                    int mode = entry.getValue();
11608                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11609                        continue;
11610                    }
11611                    if (!printed) {
11612                        pw.println("  mScreenCompatPackages:");
11613                        printed = true;
11614                    }
11615                    pw.print("    "); pw.print(pkg); pw.print(": ");
11616                            pw.print(mode); pw.println();
11617                }
11618            }
11619        }
11620        if (dumpPackage == null) {
11621            if (mSleeping || mWentToSleep || mLockScreenShown) {
11622                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11623                        + " mLockScreenShown " + mLockScreenShown);
11624            }
11625            if (mShuttingDown || mRunningVoice) {
11626                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11627            }
11628        }
11629        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11630                || mOrigWaitForDebugger) {
11631            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11632                    || dumpPackage.equals(mOrigDebugApp)) {
11633                if (needSep) {
11634                    pw.println();
11635                    needSep = false;
11636                }
11637                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11638                        + " mDebugTransient=" + mDebugTransient
11639                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11640            }
11641        }
11642        if (mOpenGlTraceApp != null) {
11643            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11644                if (needSep) {
11645                    pw.println();
11646                    needSep = false;
11647                }
11648                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11649            }
11650        }
11651        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11652                || mProfileFd != null) {
11653            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11654                if (needSep) {
11655                    pw.println();
11656                    needSep = false;
11657                }
11658                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11659                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11660                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11661                        + mAutoStopProfiler);
11662            }
11663        }
11664        if (dumpPackage == null) {
11665            if (mAlwaysFinishActivities || mController != null) {
11666                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11667                        + " mController=" + mController);
11668            }
11669            if (dumpAll) {
11670                pw.println("  Total persistent processes: " + numPers);
11671                pw.println("  mProcessesReady=" + mProcessesReady
11672                        + " mSystemReady=" + mSystemReady);
11673                pw.println("  mBooting=" + mBooting
11674                        + " mBooted=" + mBooted
11675                        + " mFactoryTest=" + mFactoryTest);
11676                pw.print("  mLastPowerCheckRealtime=");
11677                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11678                        pw.println("");
11679                pw.print("  mLastPowerCheckUptime=");
11680                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11681                        pw.println("");
11682                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11683                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11684                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11685                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11686                        + " (" + mLruProcesses.size() + " total)"
11687                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11688                        + " mNumServiceProcs=" + mNumServiceProcs
11689                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11690                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11691                        + " mLastMemoryLevel" + mLastMemoryLevel
11692                        + " mLastNumProcesses" + mLastNumProcesses);
11693                long now = SystemClock.uptimeMillis();
11694                pw.print("  mLastIdleTime=");
11695                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11696                        pw.print(" mLowRamSinceLastIdle=");
11697                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11698                        pw.println();
11699            }
11700        }
11701
11702        if (!printedAnything) {
11703            pw.println("  (nothing)");
11704        }
11705    }
11706
11707    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11708            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11709        if (mProcessesToGc.size() > 0) {
11710            boolean printed = false;
11711            long now = SystemClock.uptimeMillis();
11712            for (int i=0; i<mProcessesToGc.size(); i++) {
11713                ProcessRecord proc = mProcessesToGc.get(i);
11714                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11715                    continue;
11716                }
11717                if (!printed) {
11718                    if (needSep) pw.println();
11719                    needSep = true;
11720                    pw.println("  Processes that are waiting to GC:");
11721                    printed = true;
11722                }
11723                pw.print("    Process "); pw.println(proc);
11724                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11725                        pw.print(", last gced=");
11726                        pw.print(now-proc.lastRequestedGc);
11727                        pw.print(" ms ago, last lowMem=");
11728                        pw.print(now-proc.lastLowMemory);
11729                        pw.println(" ms ago");
11730
11731            }
11732        }
11733        return needSep;
11734    }
11735
11736    void printOomLevel(PrintWriter pw, String name, int adj) {
11737        pw.print("    ");
11738        if (adj >= 0) {
11739            pw.print(' ');
11740            if (adj < 10) pw.print(' ');
11741        } else {
11742            if (adj > -10) pw.print(' ');
11743        }
11744        pw.print(adj);
11745        pw.print(": ");
11746        pw.print(name);
11747        pw.print(" (");
11748        pw.print(mProcessList.getMemLevel(adj)/1024);
11749        pw.println(" kB)");
11750    }
11751
11752    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11753            int opti, boolean dumpAll) {
11754        boolean needSep = false;
11755
11756        if (mLruProcesses.size() > 0) {
11757            if (needSep) pw.println();
11758            needSep = true;
11759            pw.println("  OOM levels:");
11760            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11761            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11762            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11763            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11764            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11765            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11766            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11767            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11768            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11769            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11770            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11771            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11772            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11773
11774            if (needSep) pw.println();
11775            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11776                    pw.print(" total, non-act at ");
11777                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11778                    pw.print(", non-svc at ");
11779                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11780                    pw.println("):");
11781            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11782            needSep = true;
11783        }
11784
11785        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11786
11787        pw.println();
11788        pw.println("  mHomeProcess: " + mHomeProcess);
11789        pw.println("  mPreviousProcess: " + mPreviousProcess);
11790        if (mHeavyWeightProcess != null) {
11791            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11792        }
11793
11794        return true;
11795    }
11796
11797    /**
11798     * There are three ways to call this:
11799     *  - no provider specified: dump all the providers
11800     *  - a flattened component name that matched an existing provider was specified as the
11801     *    first arg: dump that one provider
11802     *  - the first arg isn't the flattened component name of an existing provider:
11803     *    dump all providers whose component contains the first arg as a substring
11804     */
11805    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11806            int opti, boolean dumpAll) {
11807        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11808    }
11809
11810    static class ItemMatcher {
11811        ArrayList<ComponentName> components;
11812        ArrayList<String> strings;
11813        ArrayList<Integer> objects;
11814        boolean all;
11815
11816        ItemMatcher() {
11817            all = true;
11818        }
11819
11820        void build(String name) {
11821            ComponentName componentName = ComponentName.unflattenFromString(name);
11822            if (componentName != null) {
11823                if (components == null) {
11824                    components = new ArrayList<ComponentName>();
11825                }
11826                components.add(componentName);
11827                all = false;
11828            } else {
11829                int objectId = 0;
11830                // Not a '/' separated full component name; maybe an object ID?
11831                try {
11832                    objectId = Integer.parseInt(name, 16);
11833                    if (objects == null) {
11834                        objects = new ArrayList<Integer>();
11835                    }
11836                    objects.add(objectId);
11837                    all = false;
11838                } catch (RuntimeException e) {
11839                    // Not an integer; just do string match.
11840                    if (strings == null) {
11841                        strings = new ArrayList<String>();
11842                    }
11843                    strings.add(name);
11844                    all = false;
11845                }
11846            }
11847        }
11848
11849        int build(String[] args, int opti) {
11850            for (; opti<args.length; opti++) {
11851                String name = args[opti];
11852                if ("--".equals(name)) {
11853                    return opti+1;
11854                }
11855                build(name);
11856            }
11857            return opti;
11858        }
11859
11860        boolean match(Object object, ComponentName comp) {
11861            if (all) {
11862                return true;
11863            }
11864            if (components != null) {
11865                for (int i=0; i<components.size(); i++) {
11866                    if (components.get(i).equals(comp)) {
11867                        return true;
11868                    }
11869                }
11870            }
11871            if (objects != null) {
11872                for (int i=0; i<objects.size(); i++) {
11873                    if (System.identityHashCode(object) == objects.get(i)) {
11874                        return true;
11875                    }
11876                }
11877            }
11878            if (strings != null) {
11879                String flat = comp.flattenToString();
11880                for (int i=0; i<strings.size(); i++) {
11881                    if (flat.contains(strings.get(i))) {
11882                        return true;
11883                    }
11884                }
11885            }
11886            return false;
11887        }
11888    }
11889
11890    /**
11891     * There are three things that cmd can be:
11892     *  - a flattened component name that matches an existing activity
11893     *  - the cmd arg isn't the flattened component name of an existing activity:
11894     *    dump all activity whose component contains the cmd as a substring
11895     *  - A hex number of the ActivityRecord object instance.
11896     */
11897    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11898            int opti, boolean dumpAll) {
11899        ArrayList<ActivityRecord> activities;
11900
11901        synchronized (this) {
11902            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11903        }
11904
11905        if (activities.size() <= 0) {
11906            return false;
11907        }
11908
11909        String[] newArgs = new String[args.length - opti];
11910        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11911
11912        TaskRecord lastTask = null;
11913        boolean needSep = false;
11914        for (int i=activities.size()-1; i>=0; i--) {
11915            ActivityRecord r = activities.get(i);
11916            if (needSep) {
11917                pw.println();
11918            }
11919            needSep = true;
11920            synchronized (this) {
11921                if (lastTask != r.task) {
11922                    lastTask = r.task;
11923                    pw.print("TASK "); pw.print(lastTask.affinity);
11924                            pw.print(" id="); pw.println(lastTask.taskId);
11925                    if (dumpAll) {
11926                        lastTask.dump(pw, "  ");
11927                    }
11928                }
11929            }
11930            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11931        }
11932        return true;
11933    }
11934
11935    /**
11936     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11937     * there is a thread associated with the activity.
11938     */
11939    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11940            final ActivityRecord r, String[] args, boolean dumpAll) {
11941        String innerPrefix = prefix + "  ";
11942        synchronized (this) {
11943            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11944                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11945                    pw.print(" pid=");
11946                    if (r.app != null) pw.println(r.app.pid);
11947                    else pw.println("(not running)");
11948            if (dumpAll) {
11949                r.dump(pw, innerPrefix);
11950            }
11951        }
11952        if (r.app != null && r.app.thread != null) {
11953            // flush anything that is already in the PrintWriter since the thread is going
11954            // to write to the file descriptor directly
11955            pw.flush();
11956            try {
11957                TransferPipe tp = new TransferPipe();
11958                try {
11959                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11960                            r.appToken, innerPrefix, args);
11961                    tp.go(fd);
11962                } finally {
11963                    tp.kill();
11964                }
11965            } catch (IOException e) {
11966                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11967            } catch (RemoteException e) {
11968                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11969            }
11970        }
11971    }
11972
11973    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11974            int opti, boolean dumpAll, String dumpPackage) {
11975        boolean needSep = false;
11976        boolean onlyHistory = false;
11977        boolean printedAnything = false;
11978
11979        if ("history".equals(dumpPackage)) {
11980            if (opti < args.length && "-s".equals(args[opti])) {
11981                dumpAll = false;
11982            }
11983            onlyHistory = true;
11984            dumpPackage = null;
11985        }
11986
11987        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11988        if (!onlyHistory && dumpAll) {
11989            if (mRegisteredReceivers.size() > 0) {
11990                boolean printed = false;
11991                Iterator it = mRegisteredReceivers.values().iterator();
11992                while (it.hasNext()) {
11993                    ReceiverList r = (ReceiverList)it.next();
11994                    if (dumpPackage != null && (r.app == null ||
11995                            !dumpPackage.equals(r.app.info.packageName))) {
11996                        continue;
11997                    }
11998                    if (!printed) {
11999                        pw.println("  Registered Receivers:");
12000                        needSep = true;
12001                        printed = true;
12002                        printedAnything = true;
12003                    }
12004                    pw.print("  * "); pw.println(r);
12005                    r.dump(pw, "    ");
12006                }
12007            }
12008
12009            if (mReceiverResolver.dump(pw, needSep ?
12010                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
12011                    "    ", dumpPackage, false)) {
12012                needSep = true;
12013                printedAnything = true;
12014            }
12015        }
12016
12017        for (BroadcastQueue q : mBroadcastQueues) {
12018            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
12019            printedAnything |= needSep;
12020        }
12021
12022        needSep = true;
12023
12024        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
12025            for (int user=0; user<mStickyBroadcasts.size(); user++) {
12026                if (needSep) {
12027                    pw.println();
12028                }
12029                needSep = true;
12030                printedAnything = true;
12031                pw.print("  Sticky broadcasts for user ");
12032                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
12033                StringBuilder sb = new StringBuilder(128);
12034                for (Map.Entry<String, ArrayList<Intent>> ent
12035                        : mStickyBroadcasts.valueAt(user).entrySet()) {
12036                    pw.print("  * Sticky action "); pw.print(ent.getKey());
12037                    if (dumpAll) {
12038                        pw.println(":");
12039                        ArrayList<Intent> intents = ent.getValue();
12040                        final int N = intents.size();
12041                        for (int i=0; i<N; i++) {
12042                            sb.setLength(0);
12043                            sb.append("    Intent: ");
12044                            intents.get(i).toShortString(sb, false, true, false, false);
12045                            pw.println(sb.toString());
12046                            Bundle bundle = intents.get(i).getExtras();
12047                            if (bundle != null) {
12048                                pw.print("      ");
12049                                pw.println(bundle.toString());
12050                            }
12051                        }
12052                    } else {
12053                        pw.println("");
12054                    }
12055                }
12056            }
12057        }
12058
12059        if (!onlyHistory && dumpAll) {
12060            pw.println();
12061            for (BroadcastQueue queue : mBroadcastQueues) {
12062                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
12063                        + queue.mBroadcastsScheduled);
12064            }
12065            pw.println("  mHandler:");
12066            mHandler.dump(new PrintWriterPrinter(pw), "    ");
12067            needSep = true;
12068            printedAnything = true;
12069        }
12070
12071        if (!printedAnything) {
12072            pw.println("  (nothing)");
12073        }
12074    }
12075
12076    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12077            int opti, boolean dumpAll, String dumpPackage) {
12078        boolean needSep;
12079        boolean printedAnything = false;
12080
12081        ItemMatcher matcher = new ItemMatcher();
12082        matcher.build(args, opti);
12083
12084        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12085
12086        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12087        printedAnything |= needSep;
12088
12089        if (mLaunchingProviders.size() > 0) {
12090            boolean printed = false;
12091            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12092                ContentProviderRecord r = mLaunchingProviders.get(i);
12093                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12094                    continue;
12095                }
12096                if (!printed) {
12097                    if (needSep) pw.println();
12098                    needSep = true;
12099                    pw.println("  Launching content providers:");
12100                    printed = true;
12101                    printedAnything = true;
12102                }
12103                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12104                        pw.println(r);
12105            }
12106        }
12107
12108        if (mGrantedUriPermissions.size() > 0) {
12109            boolean printed = false;
12110            int dumpUid = -2;
12111            if (dumpPackage != null) {
12112                try {
12113                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12114                } catch (NameNotFoundException e) {
12115                    dumpUid = -1;
12116                }
12117            }
12118            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12119                int uid = mGrantedUriPermissions.keyAt(i);
12120                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12121                    continue;
12122                }
12123                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12124                if (!printed) {
12125                    if (needSep) pw.println();
12126                    needSep = true;
12127                    pw.println("  Granted Uri Permissions:");
12128                    printed = true;
12129                    printedAnything = true;
12130                }
12131                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12132                for (UriPermission perm : perms.values()) {
12133                    pw.print("    "); pw.println(perm);
12134                    if (dumpAll) {
12135                        perm.dump(pw, "      ");
12136                    }
12137                }
12138            }
12139        }
12140
12141        if (!printedAnything) {
12142            pw.println("  (nothing)");
12143        }
12144    }
12145
12146    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12147            int opti, boolean dumpAll, String dumpPackage) {
12148        boolean printed = false;
12149
12150        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12151
12152        if (mIntentSenderRecords.size() > 0) {
12153            Iterator<WeakReference<PendingIntentRecord>> it
12154                    = mIntentSenderRecords.values().iterator();
12155            while (it.hasNext()) {
12156                WeakReference<PendingIntentRecord> ref = it.next();
12157                PendingIntentRecord rec = ref != null ? ref.get(): null;
12158                if (dumpPackage != null && (rec == null
12159                        || !dumpPackage.equals(rec.key.packageName))) {
12160                    continue;
12161                }
12162                printed = true;
12163                if (rec != null) {
12164                    pw.print("  * "); pw.println(rec);
12165                    if (dumpAll) {
12166                        rec.dump(pw, "    ");
12167                    }
12168                } else {
12169                    pw.print("  * "); pw.println(ref);
12170                }
12171            }
12172        }
12173
12174        if (!printed) {
12175            pw.println("  (nothing)");
12176        }
12177    }
12178
12179    private static final int dumpProcessList(PrintWriter pw,
12180            ActivityManagerService service, List list,
12181            String prefix, String normalLabel, String persistentLabel,
12182            String dumpPackage) {
12183        int numPers = 0;
12184        final int N = list.size()-1;
12185        for (int i=N; i>=0; i--) {
12186            ProcessRecord r = (ProcessRecord)list.get(i);
12187            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12188                continue;
12189            }
12190            pw.println(String.format("%s%s #%2d: %s",
12191                    prefix, (r.persistent ? persistentLabel : normalLabel),
12192                    i, r.toString()));
12193            if (r.persistent) {
12194                numPers++;
12195            }
12196        }
12197        return numPers;
12198    }
12199
12200    private static final boolean dumpProcessOomList(PrintWriter pw,
12201            ActivityManagerService service, List<ProcessRecord> origList,
12202            String prefix, String normalLabel, String persistentLabel,
12203            boolean inclDetails, String dumpPackage) {
12204
12205        ArrayList<Pair<ProcessRecord, Integer>> list
12206                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12207        for (int i=0; i<origList.size(); i++) {
12208            ProcessRecord r = origList.get(i);
12209            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12210                continue;
12211            }
12212            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12213        }
12214
12215        if (list.size() <= 0) {
12216            return false;
12217        }
12218
12219        Comparator<Pair<ProcessRecord, Integer>> comparator
12220                = new Comparator<Pair<ProcessRecord, Integer>>() {
12221            @Override
12222            public int compare(Pair<ProcessRecord, Integer> object1,
12223                    Pair<ProcessRecord, Integer> object2) {
12224                if (object1.first.setAdj != object2.first.setAdj) {
12225                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12226                }
12227                if (object1.second.intValue() != object2.second.intValue()) {
12228                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12229                }
12230                return 0;
12231            }
12232        };
12233
12234        Collections.sort(list, comparator);
12235
12236        final long curRealtime = SystemClock.elapsedRealtime();
12237        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12238        final long curUptime = SystemClock.uptimeMillis();
12239        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12240
12241        for (int i=list.size()-1; i>=0; i--) {
12242            ProcessRecord r = list.get(i).first;
12243            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12244            char schedGroup;
12245            switch (r.setSchedGroup) {
12246                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12247                    schedGroup = 'B';
12248                    break;
12249                case Process.THREAD_GROUP_DEFAULT:
12250                    schedGroup = 'F';
12251                    break;
12252                default:
12253                    schedGroup = '?';
12254                    break;
12255            }
12256            char foreground;
12257            if (r.foregroundActivities) {
12258                foreground = 'A';
12259            } else if (r.foregroundServices) {
12260                foreground = 'S';
12261            } else {
12262                foreground = ' ';
12263            }
12264            String procState = ProcessList.makeProcStateString(r.curProcState);
12265            pw.print(prefix);
12266            pw.print(r.persistent ? persistentLabel : normalLabel);
12267            pw.print(" #");
12268            int num = (origList.size()-1)-list.get(i).second;
12269            if (num < 10) pw.print(' ');
12270            pw.print(num);
12271            pw.print(": ");
12272            pw.print(oomAdj);
12273            pw.print(' ');
12274            pw.print(schedGroup);
12275            pw.print('/');
12276            pw.print(foreground);
12277            pw.print('/');
12278            pw.print(procState);
12279            pw.print(" trm:");
12280            if (r.trimMemoryLevel < 10) pw.print(' ');
12281            pw.print(r.trimMemoryLevel);
12282            pw.print(' ');
12283            pw.print(r.toShortString());
12284            pw.print(" (");
12285            pw.print(r.adjType);
12286            pw.println(')');
12287            if (r.adjSource != null || r.adjTarget != null) {
12288                pw.print(prefix);
12289                pw.print("    ");
12290                if (r.adjTarget instanceof ComponentName) {
12291                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12292                } else if (r.adjTarget != null) {
12293                    pw.print(r.adjTarget.toString());
12294                } else {
12295                    pw.print("{null}");
12296                }
12297                pw.print("<=");
12298                if (r.adjSource instanceof ProcessRecord) {
12299                    pw.print("Proc{");
12300                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12301                    pw.println("}");
12302                } else if (r.adjSource != null) {
12303                    pw.println(r.adjSource.toString());
12304                } else {
12305                    pw.println("{null}");
12306                }
12307            }
12308            if (inclDetails) {
12309                pw.print(prefix);
12310                pw.print("    ");
12311                pw.print("oom: max="); pw.print(r.maxAdj);
12312                pw.print(" curRaw="); pw.print(r.curRawAdj);
12313                pw.print(" setRaw="); pw.print(r.setRawAdj);
12314                pw.print(" cur="); pw.print(r.curAdj);
12315                pw.print(" set="); pw.println(r.setAdj);
12316                pw.print(prefix);
12317                pw.print("    ");
12318                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12319                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12320                pw.print(" lastPss="); pw.print(r.lastPss);
12321                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12322                pw.print(prefix);
12323                pw.print("    ");
12324                pw.print("keeping="); pw.print(r.keeping);
12325                pw.print(" cached="); pw.print(r.cached);
12326                pw.print(" empty="); pw.print(r.empty);
12327                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12328
12329                if (!r.keeping) {
12330                    if (r.lastWakeTime != 0) {
12331                        long wtime;
12332                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12333                        synchronized (stats) {
12334                            wtime = stats.getProcessWakeTime(r.info.uid,
12335                                    r.pid, curRealtime);
12336                        }
12337                        long timeUsed = wtime - r.lastWakeTime;
12338                        pw.print(prefix);
12339                        pw.print("    ");
12340                        pw.print("keep awake over ");
12341                        TimeUtils.formatDuration(realtimeSince, pw);
12342                        pw.print(" used ");
12343                        TimeUtils.formatDuration(timeUsed, pw);
12344                        pw.print(" (");
12345                        pw.print((timeUsed*100)/realtimeSince);
12346                        pw.println("%)");
12347                    }
12348                    if (r.lastCpuTime != 0) {
12349                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12350                        pw.print(prefix);
12351                        pw.print("    ");
12352                        pw.print("run cpu over ");
12353                        TimeUtils.formatDuration(uptimeSince, pw);
12354                        pw.print(" used ");
12355                        TimeUtils.formatDuration(timeUsed, pw);
12356                        pw.print(" (");
12357                        pw.print((timeUsed*100)/uptimeSince);
12358                        pw.println("%)");
12359                    }
12360                }
12361            }
12362        }
12363        return true;
12364    }
12365
12366    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12367        ArrayList<ProcessRecord> procs;
12368        synchronized (this) {
12369            if (args != null && args.length > start
12370                    && args[start].charAt(0) != '-') {
12371                procs = new ArrayList<ProcessRecord>();
12372                int pid = -1;
12373                try {
12374                    pid = Integer.parseInt(args[start]);
12375                } catch (NumberFormatException e) {
12376                }
12377                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12378                    ProcessRecord proc = mLruProcesses.get(i);
12379                    if (proc.pid == pid) {
12380                        procs.add(proc);
12381                    } else if (proc.processName.equals(args[start])) {
12382                        procs.add(proc);
12383                    }
12384                }
12385                if (procs.size() <= 0) {
12386                    return null;
12387                }
12388            } else {
12389                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12390            }
12391        }
12392        return procs;
12393    }
12394
12395    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12396            PrintWriter pw, String[] args) {
12397        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12398        if (procs == null) {
12399            pw.println("No process found for: " + args[0]);
12400            return;
12401        }
12402
12403        long uptime = SystemClock.uptimeMillis();
12404        long realtime = SystemClock.elapsedRealtime();
12405        pw.println("Applications Graphics Acceleration Info:");
12406        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12407
12408        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12409            ProcessRecord r = procs.get(i);
12410            if (r.thread != null) {
12411                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12412                pw.flush();
12413                try {
12414                    TransferPipe tp = new TransferPipe();
12415                    try {
12416                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12417                        tp.go(fd);
12418                    } finally {
12419                        tp.kill();
12420                    }
12421                } catch (IOException e) {
12422                    pw.println("Failure while dumping the app: " + r);
12423                    pw.flush();
12424                } catch (RemoteException e) {
12425                    pw.println("Got a RemoteException while dumping the app " + r);
12426                    pw.flush();
12427                }
12428            }
12429        }
12430    }
12431
12432    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12433        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12434        if (procs == null) {
12435            pw.println("No process found for: " + args[0]);
12436            return;
12437        }
12438
12439        pw.println("Applications Database Info:");
12440
12441        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12442            ProcessRecord r = procs.get(i);
12443            if (r.thread != null) {
12444                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12445                pw.flush();
12446                try {
12447                    TransferPipe tp = new TransferPipe();
12448                    try {
12449                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12450                        tp.go(fd);
12451                    } finally {
12452                        tp.kill();
12453                    }
12454                } catch (IOException e) {
12455                    pw.println("Failure while dumping the app: " + r);
12456                    pw.flush();
12457                } catch (RemoteException e) {
12458                    pw.println("Got a RemoteException while dumping the app " + r);
12459                    pw.flush();
12460                }
12461            }
12462        }
12463    }
12464
12465    final static class MemItem {
12466        final boolean isProc;
12467        final String label;
12468        final String shortLabel;
12469        final long pss;
12470        final int id;
12471        final boolean hasActivities;
12472        ArrayList<MemItem> subitems;
12473
12474        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12475                boolean _hasActivities) {
12476            isProc = true;
12477            label = _label;
12478            shortLabel = _shortLabel;
12479            pss = _pss;
12480            id = _id;
12481            hasActivities = _hasActivities;
12482        }
12483
12484        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12485            isProc = false;
12486            label = _label;
12487            shortLabel = _shortLabel;
12488            pss = _pss;
12489            id = _id;
12490            hasActivities = false;
12491        }
12492    }
12493
12494    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12495            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12496        if (sort && !isCompact) {
12497            Collections.sort(items, new Comparator<MemItem>() {
12498                @Override
12499                public int compare(MemItem lhs, MemItem rhs) {
12500                    if (lhs.pss < rhs.pss) {
12501                        return 1;
12502                    } else if (lhs.pss > rhs.pss) {
12503                        return -1;
12504                    }
12505                    return 0;
12506                }
12507            });
12508        }
12509
12510        for (int i=0; i<items.size(); i++) {
12511            MemItem mi = items.get(i);
12512            if (!isCompact) {
12513                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12514            } else if (mi.isProc) {
12515                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12516                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12517                pw.println(mi.hasActivities ? ",a" : ",e");
12518            } else {
12519                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12520                pw.println(mi.pss);
12521            }
12522            if (mi.subitems != null) {
12523                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12524                        true, isCompact);
12525            }
12526        }
12527    }
12528
12529    // These are in KB.
12530    static final long[] DUMP_MEM_BUCKETS = new long[] {
12531        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12532        120*1024, 160*1024, 200*1024,
12533        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12534        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12535    };
12536
12537    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12538            boolean stackLike) {
12539        int start = label.lastIndexOf('.');
12540        if (start >= 0) start++;
12541        else start = 0;
12542        int end = label.length();
12543        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12544            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12545                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12546                out.append(bucket);
12547                out.append(stackLike ? "MB." : "MB ");
12548                out.append(label, start, end);
12549                return;
12550            }
12551        }
12552        out.append(memKB/1024);
12553        out.append(stackLike ? "MB." : "MB ");
12554        out.append(label, start, end);
12555    }
12556
12557    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12558            ProcessList.NATIVE_ADJ,
12559            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12560            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12561            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12562            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12563            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12564    };
12565    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12566            "Native",
12567            "System", "Persistent", "Foreground",
12568            "Visible", "Perceptible",
12569            "Heavy Weight", "Backup",
12570            "A Services", "Home",
12571            "Previous", "B Services", "Cached"
12572    };
12573    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12574            "native",
12575            "sys", "pers", "fore",
12576            "vis", "percept",
12577            "heavy", "backup",
12578            "servicea", "home",
12579            "prev", "serviceb", "cached"
12580    };
12581
12582    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12583            long realtime, boolean isCheckinRequest, boolean isCompact) {
12584        if (isCheckinRequest || isCompact) {
12585            // short checkin version
12586            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12587        } else {
12588            pw.println("Applications Memory Usage (kB):");
12589            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12590        }
12591    }
12592
12593    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12594            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12595        boolean dumpDetails = false;
12596        boolean dumpFullDetails = false;
12597        boolean dumpDalvik = false;
12598        boolean oomOnly = false;
12599        boolean isCompact = false;
12600        boolean localOnly = false;
12601
12602        int opti = 0;
12603        while (opti < args.length) {
12604            String opt = args[opti];
12605            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12606                break;
12607            }
12608            opti++;
12609            if ("-a".equals(opt)) {
12610                dumpDetails = true;
12611                dumpFullDetails = true;
12612                dumpDalvik = true;
12613            } else if ("-d".equals(opt)) {
12614                dumpDalvik = true;
12615            } else if ("-c".equals(opt)) {
12616                isCompact = true;
12617            } else if ("--oom".equals(opt)) {
12618                oomOnly = true;
12619            } else if ("--local".equals(opt)) {
12620                localOnly = true;
12621            } else if ("-h".equals(opt)) {
12622                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12623                pw.println("  -a: include all available information for each process.");
12624                pw.println("  -d: include dalvik details when dumping process details.");
12625                pw.println("  -c: dump in a compact machine-parseable representation.");
12626                pw.println("  --oom: only show processes organized by oom adj.");
12627                pw.println("  --local: only collect details locally, don't call process.");
12628                pw.println("If [process] is specified it can be the name or ");
12629                pw.println("pid of a specific process to dump.");
12630                return;
12631            } else {
12632                pw.println("Unknown argument: " + opt + "; use -h for help");
12633            }
12634        }
12635
12636        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12637        long uptime = SystemClock.uptimeMillis();
12638        long realtime = SystemClock.elapsedRealtime();
12639        final long[] tmpLong = new long[1];
12640
12641        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12642        if (procs == null) {
12643            // No Java processes.  Maybe they want to print a native process.
12644            if (args != null && args.length > opti
12645                    && args[opti].charAt(0) != '-') {
12646                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12647                        = new ArrayList<ProcessCpuTracker.Stats>();
12648                updateCpuStatsNow();
12649                int findPid = -1;
12650                try {
12651                    findPid = Integer.parseInt(args[opti]);
12652                } catch (NumberFormatException e) {
12653                }
12654                synchronized (mProcessCpuThread) {
12655                    final int N = mProcessCpuTracker.countStats();
12656                    for (int i=0; i<N; i++) {
12657                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12658                        if (st.pid == findPid || (st.baseName != null
12659                                && st.baseName.equals(args[opti]))) {
12660                            nativeProcs.add(st);
12661                        }
12662                    }
12663                }
12664                if (nativeProcs.size() > 0) {
12665                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12666                            isCompact);
12667                    Debug.MemoryInfo mi = null;
12668                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12669                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12670                        final int pid = r.pid;
12671                        if (!isCheckinRequest && dumpDetails) {
12672                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12673                        }
12674                        if (mi == null) {
12675                            mi = new Debug.MemoryInfo();
12676                        }
12677                        if (dumpDetails || (!brief && !oomOnly)) {
12678                            Debug.getMemoryInfo(pid, mi);
12679                        } else {
12680                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12681                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12682                        }
12683                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12684                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12685                        if (isCheckinRequest) {
12686                            pw.println();
12687                        }
12688                    }
12689                    return;
12690                }
12691            }
12692            pw.println("No process found for: " + args[opti]);
12693            return;
12694        }
12695
12696        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12697            dumpDetails = true;
12698        }
12699
12700        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12701
12702        String[] innerArgs = new String[args.length-opti];
12703        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12704
12705        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12706        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12707        long nativePss=0, dalvikPss=0, otherPss=0;
12708        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12709
12710        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12711        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12712                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12713
12714        long totalPss = 0;
12715        long cachedPss = 0;
12716
12717        Debug.MemoryInfo mi = null;
12718        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12719            final ProcessRecord r = procs.get(i);
12720            final IApplicationThread thread;
12721            final int pid;
12722            final int oomAdj;
12723            final boolean hasActivities;
12724            synchronized (this) {
12725                thread = r.thread;
12726                pid = r.pid;
12727                oomAdj = r.getSetAdjWithServices();
12728                hasActivities = r.activities.size() > 0;
12729            }
12730            if (thread != null) {
12731                if (!isCheckinRequest && dumpDetails) {
12732                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12733                }
12734                if (mi == null) {
12735                    mi = new Debug.MemoryInfo();
12736                }
12737                if (dumpDetails || (!brief && !oomOnly)) {
12738                    Debug.getMemoryInfo(pid, mi);
12739                } else {
12740                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12741                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12742                }
12743                if (dumpDetails) {
12744                    if (localOnly) {
12745                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12746                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12747                        if (isCheckinRequest) {
12748                            pw.println();
12749                        }
12750                    } else {
12751                        try {
12752                            pw.flush();
12753                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12754                                    dumpDalvik, innerArgs);
12755                        } catch (RemoteException e) {
12756                            if (!isCheckinRequest) {
12757                                pw.println("Got RemoteException!");
12758                                pw.flush();
12759                            }
12760                        }
12761                    }
12762                }
12763
12764                final long myTotalPss = mi.getTotalPss();
12765                final long myTotalUss = mi.getTotalUss();
12766
12767                synchronized (this) {
12768                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12769                        // Record this for posterity if the process has been stable.
12770                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12771                    }
12772                }
12773
12774                if (!isCheckinRequest && mi != null) {
12775                    totalPss += myTotalPss;
12776                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12777                            (hasActivities ? " / activities)" : ")"),
12778                            r.processName, myTotalPss, pid, hasActivities);
12779                    procMems.add(pssItem);
12780                    procMemsMap.put(pid, pssItem);
12781
12782                    nativePss += mi.nativePss;
12783                    dalvikPss += mi.dalvikPss;
12784                    otherPss += mi.otherPss;
12785                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12786                        long mem = mi.getOtherPss(j);
12787                        miscPss[j] += mem;
12788                        otherPss -= mem;
12789                    }
12790
12791                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12792                        cachedPss += myTotalPss;
12793                    }
12794
12795                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12796                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12797                                || oomIndex == (oomPss.length-1)) {
12798                            oomPss[oomIndex] += myTotalPss;
12799                            if (oomProcs[oomIndex] == null) {
12800                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12801                            }
12802                            oomProcs[oomIndex].add(pssItem);
12803                            break;
12804                        }
12805                    }
12806                }
12807            }
12808        }
12809
12810        long nativeProcTotalPss = 0;
12811
12812        if (!isCheckinRequest && procs.size() > 1) {
12813            // If we are showing aggregations, also look for native processes to
12814            // include so that our aggregations are more accurate.
12815            updateCpuStatsNow();
12816            synchronized (mProcessCpuThread) {
12817                final int N = mProcessCpuTracker.countStats();
12818                for (int i=0; i<N; i++) {
12819                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12820                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12821                        if (mi == null) {
12822                            mi = new Debug.MemoryInfo();
12823                        }
12824                        if (!brief && !oomOnly) {
12825                            Debug.getMemoryInfo(st.pid, mi);
12826                        } else {
12827                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12828                            mi.nativePrivateDirty = (int)tmpLong[0];
12829                        }
12830
12831                        final long myTotalPss = mi.getTotalPss();
12832                        totalPss += myTotalPss;
12833                        nativeProcTotalPss += myTotalPss;
12834
12835                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12836                                st.name, myTotalPss, st.pid, false);
12837                        procMems.add(pssItem);
12838
12839                        nativePss += mi.nativePss;
12840                        dalvikPss += mi.dalvikPss;
12841                        otherPss += mi.otherPss;
12842                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12843                            long mem = mi.getOtherPss(j);
12844                            miscPss[j] += mem;
12845                            otherPss -= mem;
12846                        }
12847                        oomPss[0] += myTotalPss;
12848                        if (oomProcs[0] == null) {
12849                            oomProcs[0] = new ArrayList<MemItem>();
12850                        }
12851                        oomProcs[0].add(pssItem);
12852                    }
12853                }
12854            }
12855
12856            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12857
12858            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12859            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12860            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12861            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12862                String label = Debug.MemoryInfo.getOtherLabel(j);
12863                catMems.add(new MemItem(label, label, miscPss[j], j));
12864            }
12865
12866            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12867            for (int j=0; j<oomPss.length; j++) {
12868                if (oomPss[j] != 0) {
12869                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12870                            : DUMP_MEM_OOM_LABEL[j];
12871                    MemItem item = new MemItem(label, label, oomPss[j],
12872                            DUMP_MEM_OOM_ADJ[j]);
12873                    item.subitems = oomProcs[j];
12874                    oomMems.add(item);
12875                }
12876            }
12877
12878            if (!brief && !oomOnly && !isCompact) {
12879                pw.println();
12880                pw.println("Total PSS by process:");
12881                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12882                pw.println();
12883            }
12884            if (!isCompact) {
12885                pw.println("Total PSS by OOM adjustment:");
12886            }
12887            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12888            if (!brief && !oomOnly) {
12889                PrintWriter out = categoryPw != null ? categoryPw : pw;
12890                if (!isCompact) {
12891                    out.println();
12892                    out.println("Total PSS by category:");
12893                }
12894                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12895            }
12896            if (!isCompact) {
12897                pw.println();
12898            }
12899            MemInfoReader memInfo = new MemInfoReader();
12900            memInfo.readMemInfo();
12901            if (nativeProcTotalPss > 0) {
12902                synchronized (this) {
12903                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
12904                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
12905                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
12906                            nativeProcTotalPss);
12907                }
12908            }
12909            if (!brief) {
12910                if (!isCompact) {
12911                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12912                    pw.print(" kB (status ");
12913                    switch (mLastMemoryLevel) {
12914                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12915                            pw.println("normal)");
12916                            break;
12917                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12918                            pw.println("moderate)");
12919                            break;
12920                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12921                            pw.println("low)");
12922                            break;
12923                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12924                            pw.println("critical)");
12925                            break;
12926                        default:
12927                            pw.print(mLastMemoryLevel);
12928                            pw.println(")");
12929                            break;
12930                    }
12931                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12932                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12933                            pw.print(cachedPss); pw.print(" cached pss + ");
12934                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12935                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12936                } else {
12937                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12938                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12939                            + memInfo.getFreeSizeKb()); pw.print(",");
12940                    pw.println(totalPss - cachedPss);
12941                }
12942            }
12943            if (!isCompact) {
12944                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12945                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12946                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12947                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12948                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12949                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12950                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12951                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12952                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12953                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12954                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12955            }
12956            if (!brief) {
12957                if (memInfo.getZramTotalSizeKb() != 0) {
12958                    if (!isCompact) {
12959                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12960                                pw.print(" kB physical used for ");
12961                                pw.print(memInfo.getSwapTotalSizeKb()
12962                                        - memInfo.getSwapFreeSizeKb());
12963                                pw.print(" kB in swap (");
12964                                pw.print(memInfo.getSwapTotalSizeKb());
12965                                pw.println(" kB total swap)");
12966                    } else {
12967                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12968                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12969                                pw.println(memInfo.getSwapFreeSizeKb());
12970                    }
12971                }
12972                final int[] SINGLE_LONG_FORMAT = new int[] {
12973                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12974                };
12975                long[] longOut = new long[1];
12976                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12977                        SINGLE_LONG_FORMAT, null, longOut, null);
12978                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12979                longOut[0] = 0;
12980                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12981                        SINGLE_LONG_FORMAT, null, longOut, null);
12982                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12983                longOut[0] = 0;
12984                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12985                        SINGLE_LONG_FORMAT, null, longOut, null);
12986                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12987                longOut[0] = 0;
12988                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12989                        SINGLE_LONG_FORMAT, null, longOut, null);
12990                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12991                if (!isCompact) {
12992                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12993                        pw.print("      KSM: "); pw.print(sharing);
12994                                pw.print(" kB saved from shared ");
12995                                pw.print(shared); pw.println(" kB");
12996                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12997                                pw.print(voltile); pw.println(" kB volatile");
12998                    }
12999                    pw.print("   Tuning: ");
13000                    pw.print(ActivityManager.staticGetMemoryClass());
13001                    pw.print(" (large ");
13002                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13003                    pw.print("), oom ");
13004                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13005                    pw.print(" kB");
13006                    pw.print(", restore limit ");
13007                    pw.print(mProcessList.getCachedRestoreThresholdKb());
13008                    pw.print(" kB");
13009                    if (ActivityManager.isLowRamDeviceStatic()) {
13010                        pw.print(" (low-ram)");
13011                    }
13012                    if (ActivityManager.isHighEndGfx()) {
13013                        pw.print(" (high-end-gfx)");
13014                    }
13015                    pw.println();
13016                } else {
13017                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
13018                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
13019                    pw.println(voltile);
13020                    pw.print("tuning,");
13021                    pw.print(ActivityManager.staticGetMemoryClass());
13022                    pw.print(',');
13023                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13024                    pw.print(',');
13025                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13026                    if (ActivityManager.isLowRamDeviceStatic()) {
13027                        pw.print(",low-ram");
13028                    }
13029                    if (ActivityManager.isHighEndGfx()) {
13030                        pw.print(",high-end-gfx");
13031                    }
13032                    pw.println();
13033                }
13034            }
13035        }
13036    }
13037
13038    /**
13039     * Searches array of arguments for the specified string
13040     * @param args array of argument strings
13041     * @param value value to search for
13042     * @return true if the value is contained in the array
13043     */
13044    private static boolean scanArgs(String[] args, String value) {
13045        if (args != null) {
13046            for (String arg : args) {
13047                if (value.equals(arg)) {
13048                    return true;
13049                }
13050            }
13051        }
13052        return false;
13053    }
13054
13055    private final boolean removeDyingProviderLocked(ProcessRecord proc,
13056            ContentProviderRecord cpr, boolean always) {
13057        final boolean inLaunching = mLaunchingProviders.contains(cpr);
13058
13059        if (!inLaunching || always) {
13060            synchronized (cpr) {
13061                cpr.launchingApp = null;
13062                cpr.notifyAll();
13063            }
13064            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
13065            String names[] = cpr.info.authority.split(";");
13066            for (int j = 0; j < names.length; j++) {
13067                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
13068            }
13069        }
13070
13071        for (int i=0; i<cpr.connections.size(); i++) {
13072            ContentProviderConnection conn = cpr.connections.get(i);
13073            if (conn.waiting) {
13074                // If this connection is waiting for the provider, then we don't
13075                // need to mess with its process unless we are always removing
13076                // or for some reason the provider is not currently launching.
13077                if (inLaunching && !always) {
13078                    continue;
13079                }
13080            }
13081            ProcessRecord capp = conn.client;
13082            conn.dead = true;
13083            if (conn.stableCount > 0) {
13084                if (!capp.persistent && capp.thread != null
13085                        && capp.pid != 0
13086                        && capp.pid != MY_PID) {
13087                    killUnneededProcessLocked(capp, "depends on provider "
13088                            + cpr.name.flattenToShortString()
13089                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13090                }
13091            } else if (capp.thread != null && conn.provider.provider != null) {
13092                try {
13093                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13094                } catch (RemoteException e) {
13095                }
13096                // In the protocol here, we don't expect the client to correctly
13097                // clean up this connection, we'll just remove it.
13098                cpr.connections.remove(i);
13099                conn.client.conProviders.remove(conn);
13100            }
13101        }
13102
13103        if (inLaunching && always) {
13104            mLaunchingProviders.remove(cpr);
13105        }
13106        return inLaunching;
13107    }
13108
13109    /**
13110     * Main code for cleaning up a process when it has gone away.  This is
13111     * called both as a result of the process dying, or directly when stopping
13112     * a process when running in single process mode.
13113     */
13114    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13115            boolean restarting, boolean allowRestart, int index) {
13116        if (index >= 0) {
13117            removeLruProcessLocked(app);
13118            ProcessList.remove(app.pid);
13119        }
13120
13121        mProcessesToGc.remove(app);
13122        mPendingPssProcesses.remove(app);
13123
13124        // Dismiss any open dialogs.
13125        if (app.crashDialog != null && !app.forceCrashReport) {
13126            app.crashDialog.dismiss();
13127            app.crashDialog = null;
13128        }
13129        if (app.anrDialog != null) {
13130            app.anrDialog.dismiss();
13131            app.anrDialog = null;
13132        }
13133        if (app.waitDialog != null) {
13134            app.waitDialog.dismiss();
13135            app.waitDialog = null;
13136        }
13137
13138        app.crashing = false;
13139        app.notResponding = false;
13140
13141        app.resetPackageList(mProcessStats);
13142        app.unlinkDeathRecipient();
13143        app.makeInactive(mProcessStats);
13144        app.waitingToKill = null;
13145        app.forcingToForeground = null;
13146        updateProcessForegroundLocked(app, false, false);
13147        app.foregroundActivities = false;
13148        app.hasShownUi = false;
13149        app.treatLikeActivity = false;
13150        app.hasAboveClient = false;
13151        app.hasClientActivities = false;
13152
13153        mServices.killServicesLocked(app, allowRestart);
13154
13155        boolean restart = false;
13156
13157        // Remove published content providers.
13158        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13159            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13160            final boolean always = app.bad || !allowRestart;
13161            if (removeDyingProviderLocked(app, cpr, always) || always) {
13162                // We left the provider in the launching list, need to
13163                // restart it.
13164                restart = true;
13165            }
13166
13167            cpr.provider = null;
13168            cpr.proc = null;
13169        }
13170        app.pubProviders.clear();
13171
13172        // Take care of any launching providers waiting for this process.
13173        if (checkAppInLaunchingProvidersLocked(app, false)) {
13174            restart = true;
13175        }
13176
13177        // Unregister from connected content providers.
13178        if (!app.conProviders.isEmpty()) {
13179            for (int i=0; i<app.conProviders.size(); i++) {
13180                ContentProviderConnection conn = app.conProviders.get(i);
13181                conn.provider.connections.remove(conn);
13182            }
13183            app.conProviders.clear();
13184        }
13185
13186        // At this point there may be remaining entries in mLaunchingProviders
13187        // where we were the only one waiting, so they are no longer of use.
13188        // Look for these and clean up if found.
13189        // XXX Commented out for now.  Trying to figure out a way to reproduce
13190        // the actual situation to identify what is actually going on.
13191        if (false) {
13192            for (int i=0; i<mLaunchingProviders.size(); i++) {
13193                ContentProviderRecord cpr = (ContentProviderRecord)
13194                        mLaunchingProviders.get(i);
13195                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13196                    synchronized (cpr) {
13197                        cpr.launchingApp = null;
13198                        cpr.notifyAll();
13199                    }
13200                }
13201            }
13202        }
13203
13204        skipCurrentReceiverLocked(app);
13205
13206        // Unregister any receivers.
13207        for (int i=app.receivers.size()-1; i>=0; i--) {
13208            removeReceiverLocked(app.receivers.valueAt(i));
13209        }
13210        app.receivers.clear();
13211
13212        // If the app is undergoing backup, tell the backup manager about it
13213        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13214            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13215                    + mBackupTarget.appInfo + " died during backup");
13216            try {
13217                IBackupManager bm = IBackupManager.Stub.asInterface(
13218                        ServiceManager.getService(Context.BACKUP_SERVICE));
13219                bm.agentDisconnected(app.info.packageName);
13220            } catch (RemoteException e) {
13221                // can't happen; backup manager is local
13222            }
13223        }
13224
13225        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13226            ProcessChangeItem item = mPendingProcessChanges.get(i);
13227            if (item.pid == app.pid) {
13228                mPendingProcessChanges.remove(i);
13229                mAvailProcessChanges.add(item);
13230            }
13231        }
13232        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13233
13234        // If the caller is restarting this app, then leave it in its
13235        // current lists and let the caller take care of it.
13236        if (restarting) {
13237            return;
13238        }
13239
13240        if (!app.persistent || app.isolated) {
13241            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13242                    "Removing non-persistent process during cleanup: " + app);
13243            mProcessNames.remove(app.processName, app.uid);
13244            mIsolatedProcesses.remove(app.uid);
13245            if (mHeavyWeightProcess == app) {
13246                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13247                        mHeavyWeightProcess.userId, 0));
13248                mHeavyWeightProcess = null;
13249            }
13250        } else if (!app.removed) {
13251            // This app is persistent, so we need to keep its record around.
13252            // If it is not already on the pending app list, add it there
13253            // and start a new process for it.
13254            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13255                mPersistentStartingProcesses.add(app);
13256                restart = true;
13257            }
13258        }
13259        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13260                "Clean-up removing on hold: " + app);
13261        mProcessesOnHold.remove(app);
13262
13263        if (app == mHomeProcess) {
13264            mHomeProcess = null;
13265        }
13266        if (app == mPreviousProcess) {
13267            mPreviousProcess = null;
13268        }
13269
13270        if (restart && !app.isolated) {
13271            // We have components that still need to be running in the
13272            // process, so re-launch it.
13273            mProcessNames.put(app.processName, app.uid, app);
13274            startProcessLocked(app, "restart", app.processName, null /* ABI override */);
13275        } else if (app.pid > 0 && app.pid != MY_PID) {
13276            // Goodbye!
13277            boolean removed;
13278            synchronized (mPidsSelfLocked) {
13279                mPidsSelfLocked.remove(app.pid);
13280                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13281            }
13282            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
13283            if (app.isolated) {
13284                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13285            }
13286            app.setPid(0);
13287        }
13288    }
13289
13290    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13291        // Look through the content providers we are waiting to have launched,
13292        // and if any run in this process then either schedule a restart of
13293        // the process or kill the client waiting for it if this process has
13294        // gone bad.
13295        int NL = mLaunchingProviders.size();
13296        boolean restart = false;
13297        for (int i=0; i<NL; i++) {
13298            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13299            if (cpr.launchingApp == app) {
13300                if (!alwaysBad && !app.bad) {
13301                    restart = true;
13302                } else {
13303                    removeDyingProviderLocked(app, cpr, true);
13304                    // cpr should have been removed from mLaunchingProviders
13305                    NL = mLaunchingProviders.size();
13306                    i--;
13307                }
13308            }
13309        }
13310        return restart;
13311    }
13312
13313    // =========================================================
13314    // SERVICES
13315    // =========================================================
13316
13317    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13318            int flags) {
13319        enforceNotIsolatedCaller("getServices");
13320        synchronized (this) {
13321            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13322        }
13323    }
13324
13325    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13326        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13327        synchronized (this) {
13328            return mServices.getRunningServiceControlPanelLocked(name);
13329        }
13330    }
13331
13332    public ComponentName startService(IApplicationThread caller, Intent service,
13333            String resolvedType, int userId) {
13334        enforceNotIsolatedCaller("startService");
13335        // Refuse possible leaked file descriptors
13336        if (service != null && service.hasFileDescriptors() == true) {
13337            throw new IllegalArgumentException("File descriptors passed in Intent");
13338        }
13339
13340        if (DEBUG_SERVICE)
13341            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13342        synchronized(this) {
13343            final int callingPid = Binder.getCallingPid();
13344            final int callingUid = Binder.getCallingUid();
13345            final long origId = Binder.clearCallingIdentity();
13346            ComponentName res = mServices.startServiceLocked(caller, service,
13347                    resolvedType, callingPid, callingUid, userId);
13348            Binder.restoreCallingIdentity(origId);
13349            return res;
13350        }
13351    }
13352
13353    ComponentName startServiceInPackage(int uid,
13354            Intent service, String resolvedType, int userId) {
13355        synchronized(this) {
13356            if (DEBUG_SERVICE)
13357                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13358            final long origId = Binder.clearCallingIdentity();
13359            ComponentName res = mServices.startServiceLocked(null, service,
13360                    resolvedType, -1, uid, userId);
13361            Binder.restoreCallingIdentity(origId);
13362            return res;
13363        }
13364    }
13365
13366    public int stopService(IApplicationThread caller, Intent service,
13367            String resolvedType, int userId) {
13368        enforceNotIsolatedCaller("stopService");
13369        // Refuse possible leaked file descriptors
13370        if (service != null && service.hasFileDescriptors() == true) {
13371            throw new IllegalArgumentException("File descriptors passed in Intent");
13372        }
13373
13374        synchronized(this) {
13375            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13376        }
13377    }
13378
13379    public IBinder peekService(Intent service, String resolvedType) {
13380        enforceNotIsolatedCaller("peekService");
13381        // Refuse possible leaked file descriptors
13382        if (service != null && service.hasFileDescriptors() == true) {
13383            throw new IllegalArgumentException("File descriptors passed in Intent");
13384        }
13385        synchronized(this) {
13386            return mServices.peekServiceLocked(service, resolvedType);
13387        }
13388    }
13389
13390    public boolean stopServiceToken(ComponentName className, IBinder token,
13391            int startId) {
13392        synchronized(this) {
13393            return mServices.stopServiceTokenLocked(className, token, startId);
13394        }
13395    }
13396
13397    public void setServiceForeground(ComponentName className, IBinder token,
13398            int id, Notification notification, boolean removeNotification) {
13399        synchronized(this) {
13400            mServices.setServiceForegroundLocked(className, token, id, notification,
13401                    removeNotification);
13402        }
13403    }
13404
13405    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13406            boolean requireFull, String name, String callerPackage) {
13407        final int callingUserId = UserHandle.getUserId(callingUid);
13408        if (callingUserId != userId) {
13409            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13410                if ((requireFull || checkComponentPermission(
13411                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13412                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
13413                        && checkComponentPermission(INTERACT_ACROSS_USERS_FULL,
13414                                callingPid, callingUid, -1, true)
13415                                != PackageManager.PERMISSION_GRANTED) {
13416                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13417                        // In this case, they would like to just execute as their
13418                        // owner user instead of failing.
13419                        userId = callingUserId;
13420                    } else {
13421                        StringBuilder builder = new StringBuilder(128);
13422                        builder.append("Permission Denial: ");
13423                        builder.append(name);
13424                        if (callerPackage != null) {
13425                            builder.append(" from ");
13426                            builder.append(callerPackage);
13427                        }
13428                        builder.append(" asks to run as user ");
13429                        builder.append(userId);
13430                        builder.append(" but is calling from user ");
13431                        builder.append(UserHandle.getUserId(callingUid));
13432                        builder.append("; this requires ");
13433                        builder.append(INTERACT_ACROSS_USERS_FULL);
13434                        if (!requireFull) {
13435                            builder.append(" or ");
13436                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
13437                        }
13438                        String msg = builder.toString();
13439                        Slog.w(TAG, msg);
13440                        throw new SecurityException(msg);
13441                    }
13442                }
13443            }
13444            if (userId == UserHandle.USER_CURRENT
13445                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
13446                // Note that we may be accessing this outside of a lock...
13447                // shouldn't be a big deal, if this is being called outside
13448                // of a locked context there is intrinsically a race with
13449                // the value the caller will receive and someone else changing it.
13450                userId = mCurrentUserId;
13451            }
13452            if (!allowAll && userId < 0) {
13453                throw new IllegalArgumentException(
13454                        "Call does not support special user #" + userId);
13455            }
13456        }
13457        return userId;
13458    }
13459
13460    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13461            String className, int flags) {
13462        boolean result = false;
13463        // For apps that don't have pre-defined UIDs, check for permission
13464        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13465            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13466                if (ActivityManager.checkUidPermission(
13467                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13468                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13469                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13470                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13471                            + " requests FLAG_SINGLE_USER, but app does not hold "
13472                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
13473                    Slog.w(TAG, msg);
13474                    throw new SecurityException(msg);
13475                }
13476                // Permission passed
13477                result = true;
13478            }
13479        } else if ("system".equals(componentProcessName)) {
13480            result = true;
13481        } else {
13482            // App with pre-defined UID, check if it's a persistent app
13483            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13484        }
13485        if (DEBUG_MU) {
13486            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13487                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13488        }
13489        return result;
13490    }
13491
13492    /**
13493     * Checks to see if the caller is in the same app as the singleton
13494     * component, or the component is in a special app. It allows special apps
13495     * to export singleton components but prevents exporting singleton
13496     * components for regular apps.
13497     */
13498    boolean isValidSingletonCall(int callingUid, int componentUid) {
13499        int componentAppId = UserHandle.getAppId(componentUid);
13500        return UserHandle.isSameApp(callingUid, componentUid)
13501                || componentAppId == Process.SYSTEM_UID
13502                || componentAppId == Process.PHONE_UID
13503                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13504                        == PackageManager.PERMISSION_GRANTED;
13505    }
13506
13507    public int bindService(IApplicationThread caller, IBinder token,
13508            Intent service, String resolvedType,
13509            IServiceConnection connection, int flags, int userId) {
13510        enforceNotIsolatedCaller("bindService");
13511        // Refuse possible leaked file descriptors
13512        if (service != null && service.hasFileDescriptors() == true) {
13513            throw new IllegalArgumentException("File descriptors passed in Intent");
13514        }
13515
13516        synchronized(this) {
13517            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13518                    connection, flags, userId);
13519        }
13520    }
13521
13522    public boolean unbindService(IServiceConnection connection) {
13523        synchronized (this) {
13524            return mServices.unbindServiceLocked(connection);
13525        }
13526    }
13527
13528    public void publishService(IBinder token, Intent intent, IBinder service) {
13529        // Refuse possible leaked file descriptors
13530        if (intent != null && intent.hasFileDescriptors() == true) {
13531            throw new IllegalArgumentException("File descriptors passed in Intent");
13532        }
13533
13534        synchronized(this) {
13535            if (!(token instanceof ServiceRecord)) {
13536                throw new IllegalArgumentException("Invalid service token");
13537            }
13538            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13539        }
13540    }
13541
13542    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13543        // Refuse possible leaked file descriptors
13544        if (intent != null && intent.hasFileDescriptors() == true) {
13545            throw new IllegalArgumentException("File descriptors passed in Intent");
13546        }
13547
13548        synchronized(this) {
13549            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13550        }
13551    }
13552
13553    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13554        synchronized(this) {
13555            if (!(token instanceof ServiceRecord)) {
13556                throw new IllegalArgumentException("Invalid service token");
13557            }
13558            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13559        }
13560    }
13561
13562    // =========================================================
13563    // BACKUP AND RESTORE
13564    // =========================================================
13565
13566    // Cause the target app to be launched if necessary and its backup agent
13567    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13568    // activity manager to announce its creation.
13569    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13570        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13571        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
13572
13573        synchronized(this) {
13574            // !!! TODO: currently no check here that we're already bound
13575            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13576            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13577            synchronized (stats) {
13578                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13579            }
13580
13581            // Backup agent is now in use, its package can't be stopped.
13582            try {
13583                AppGlobals.getPackageManager().setPackageStoppedState(
13584                        app.packageName, false, UserHandle.getUserId(app.uid));
13585            } catch (RemoteException e) {
13586            } catch (IllegalArgumentException e) {
13587                Slog.w(TAG, "Failed trying to unstop package "
13588                        + app.packageName + ": " + e);
13589            }
13590
13591            BackupRecord r = new BackupRecord(ss, app, backupMode);
13592            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13593                    ? new ComponentName(app.packageName, app.backupAgentName)
13594                    : new ComponentName("android", "FullBackupAgent");
13595            // startProcessLocked() returns existing proc's record if it's already running
13596            ProcessRecord proc = startProcessLocked(app.processName, app,
13597                    false, 0, "backup", hostingName, false, false, false);
13598            if (proc == null) {
13599                Slog.e(TAG, "Unable to start backup agent process " + r);
13600                return false;
13601            }
13602
13603            r.app = proc;
13604            mBackupTarget = r;
13605            mBackupAppName = app.packageName;
13606
13607            // Try not to kill the process during backup
13608            updateOomAdjLocked(proc);
13609
13610            // If the process is already attached, schedule the creation of the backup agent now.
13611            // If it is not yet live, this will be done when it attaches to the framework.
13612            if (proc.thread != null) {
13613                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13614                try {
13615                    proc.thread.scheduleCreateBackupAgent(app,
13616                            compatibilityInfoForPackageLocked(app), backupMode);
13617                } catch (RemoteException e) {
13618                    // Will time out on the backup manager side
13619                }
13620            } else {
13621                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13622            }
13623            // Invariants: at this point, the target app process exists and the application
13624            // is either already running or in the process of coming up.  mBackupTarget and
13625            // mBackupAppName describe the app, so that when it binds back to the AM we
13626            // know that it's scheduled for a backup-agent operation.
13627        }
13628
13629        return true;
13630    }
13631
13632    @Override
13633    public void clearPendingBackup() {
13634        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13635        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13636
13637        synchronized (this) {
13638            mBackupTarget = null;
13639            mBackupAppName = null;
13640        }
13641    }
13642
13643    // A backup agent has just come up
13644    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13645        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13646                + " = " + agent);
13647
13648        synchronized(this) {
13649            if (!agentPackageName.equals(mBackupAppName)) {
13650                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13651                return;
13652            }
13653        }
13654
13655        long oldIdent = Binder.clearCallingIdentity();
13656        try {
13657            IBackupManager bm = IBackupManager.Stub.asInterface(
13658                    ServiceManager.getService(Context.BACKUP_SERVICE));
13659            bm.agentConnected(agentPackageName, agent);
13660        } catch (RemoteException e) {
13661            // can't happen; the backup manager service is local
13662        } catch (Exception e) {
13663            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13664            e.printStackTrace();
13665        } finally {
13666            Binder.restoreCallingIdentity(oldIdent);
13667        }
13668    }
13669
13670    // done with this agent
13671    public void unbindBackupAgent(ApplicationInfo appInfo) {
13672        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13673        if (appInfo == null) {
13674            Slog.w(TAG, "unbind backup agent for null app");
13675            return;
13676        }
13677
13678        synchronized(this) {
13679            try {
13680                if (mBackupAppName == null) {
13681                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13682                    return;
13683                }
13684
13685                if (!mBackupAppName.equals(appInfo.packageName)) {
13686                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13687                    return;
13688                }
13689
13690                // Not backing this app up any more; reset its OOM adjustment
13691                final ProcessRecord proc = mBackupTarget.app;
13692                updateOomAdjLocked(proc);
13693
13694                // If the app crashed during backup, 'thread' will be null here
13695                if (proc.thread != null) {
13696                    try {
13697                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13698                                compatibilityInfoForPackageLocked(appInfo));
13699                    } catch (Exception e) {
13700                        Slog.e(TAG, "Exception when unbinding backup agent:");
13701                        e.printStackTrace();
13702                    }
13703                }
13704            } finally {
13705                mBackupTarget = null;
13706                mBackupAppName = null;
13707            }
13708        }
13709    }
13710    // =========================================================
13711    // BROADCASTS
13712    // =========================================================
13713
13714    private final List getStickiesLocked(String action, IntentFilter filter,
13715            List cur, int userId) {
13716        final ContentResolver resolver = mContext.getContentResolver();
13717        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13718        if (stickies == null) {
13719            return cur;
13720        }
13721        final ArrayList<Intent> list = stickies.get(action);
13722        if (list == null) {
13723            return cur;
13724        }
13725        int N = list.size();
13726        for (int i=0; i<N; i++) {
13727            Intent intent = list.get(i);
13728            if (filter.match(resolver, intent, true, TAG) >= 0) {
13729                if (cur == null) {
13730                    cur = new ArrayList<Intent>();
13731                }
13732                cur.add(intent);
13733            }
13734        }
13735        return cur;
13736    }
13737
13738    boolean isPendingBroadcastProcessLocked(int pid) {
13739        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13740                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13741    }
13742
13743    void skipPendingBroadcastLocked(int pid) {
13744            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13745            for (BroadcastQueue queue : mBroadcastQueues) {
13746                queue.skipPendingBroadcastLocked(pid);
13747            }
13748    }
13749
13750    // The app just attached; send any pending broadcasts that it should receive
13751    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13752        boolean didSomething = false;
13753        for (BroadcastQueue queue : mBroadcastQueues) {
13754            didSomething |= queue.sendPendingBroadcastsLocked(app);
13755        }
13756        return didSomething;
13757    }
13758
13759    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13760            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13761        enforceNotIsolatedCaller("registerReceiver");
13762        int callingUid;
13763        int callingPid;
13764        synchronized(this) {
13765            ProcessRecord callerApp = null;
13766            if (caller != null) {
13767                callerApp = getRecordForAppLocked(caller);
13768                if (callerApp == null) {
13769                    throw new SecurityException(
13770                            "Unable to find app for caller " + caller
13771                            + " (pid=" + Binder.getCallingPid()
13772                            + ") when registering receiver " + receiver);
13773                }
13774                if (callerApp.info.uid != Process.SYSTEM_UID &&
13775                        !callerApp.pkgList.containsKey(callerPackage) &&
13776                        !"android".equals(callerPackage)) {
13777                    throw new SecurityException("Given caller package " + callerPackage
13778                            + " is not running in process " + callerApp);
13779                }
13780                callingUid = callerApp.info.uid;
13781                callingPid = callerApp.pid;
13782            } else {
13783                callerPackage = null;
13784                callingUid = Binder.getCallingUid();
13785                callingPid = Binder.getCallingPid();
13786            }
13787
13788            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13789                    true, true, "registerReceiver", callerPackage);
13790
13791            List allSticky = null;
13792
13793            // Look for any matching sticky broadcasts...
13794            Iterator actions = filter.actionsIterator();
13795            if (actions != null) {
13796                while (actions.hasNext()) {
13797                    String action = (String)actions.next();
13798                    allSticky = getStickiesLocked(action, filter, allSticky,
13799                            UserHandle.USER_ALL);
13800                    allSticky = getStickiesLocked(action, filter, allSticky,
13801                            UserHandle.getUserId(callingUid));
13802                }
13803            } else {
13804                allSticky = getStickiesLocked(null, filter, allSticky,
13805                        UserHandle.USER_ALL);
13806                allSticky = getStickiesLocked(null, filter, allSticky,
13807                        UserHandle.getUserId(callingUid));
13808            }
13809
13810            // The first sticky in the list is returned directly back to
13811            // the client.
13812            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13813
13814            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13815                    + ": " + sticky);
13816
13817            if (receiver == null) {
13818                return sticky;
13819            }
13820
13821            ReceiverList rl
13822                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13823            if (rl == null) {
13824                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13825                        userId, receiver);
13826                if (rl.app != null) {
13827                    rl.app.receivers.add(rl);
13828                } else {
13829                    try {
13830                        receiver.asBinder().linkToDeath(rl, 0);
13831                    } catch (RemoteException e) {
13832                        return sticky;
13833                    }
13834                    rl.linkedToDeath = true;
13835                }
13836                mRegisteredReceivers.put(receiver.asBinder(), rl);
13837            } else if (rl.uid != callingUid) {
13838                throw new IllegalArgumentException(
13839                        "Receiver requested to register for uid " + callingUid
13840                        + " was previously registered for uid " + rl.uid);
13841            } else if (rl.pid != callingPid) {
13842                throw new IllegalArgumentException(
13843                        "Receiver requested to register for pid " + callingPid
13844                        + " was previously registered for pid " + rl.pid);
13845            } else if (rl.userId != userId) {
13846                throw new IllegalArgumentException(
13847                        "Receiver requested to register for user " + userId
13848                        + " was previously registered for user " + rl.userId);
13849            }
13850            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13851                    permission, callingUid, userId);
13852            rl.add(bf);
13853            if (!bf.debugCheck()) {
13854                Slog.w(TAG, "==> For Dynamic broadast");
13855            }
13856            mReceiverResolver.addFilter(bf);
13857
13858            // Enqueue broadcasts for all existing stickies that match
13859            // this filter.
13860            if (allSticky != null) {
13861                ArrayList receivers = new ArrayList();
13862                receivers.add(bf);
13863
13864                int N = allSticky.size();
13865                for (int i=0; i<N; i++) {
13866                    Intent intent = (Intent)allSticky.get(i);
13867                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13868                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13869                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13870                            null, null, false, true, true, -1);
13871                    queue.enqueueParallelBroadcastLocked(r);
13872                    queue.scheduleBroadcastsLocked();
13873                }
13874            }
13875
13876            return sticky;
13877        }
13878    }
13879
13880    public void unregisterReceiver(IIntentReceiver receiver) {
13881        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13882
13883        final long origId = Binder.clearCallingIdentity();
13884        try {
13885            boolean doTrim = false;
13886
13887            synchronized(this) {
13888                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13889                if (rl != null) {
13890                    if (rl.curBroadcast != null) {
13891                        BroadcastRecord r = rl.curBroadcast;
13892                        final boolean doNext = finishReceiverLocked(
13893                                receiver.asBinder(), r.resultCode, r.resultData,
13894                                r.resultExtras, r.resultAbort);
13895                        if (doNext) {
13896                            doTrim = true;
13897                            r.queue.processNextBroadcast(false);
13898                        }
13899                    }
13900
13901                    if (rl.app != null) {
13902                        rl.app.receivers.remove(rl);
13903                    }
13904                    removeReceiverLocked(rl);
13905                    if (rl.linkedToDeath) {
13906                        rl.linkedToDeath = false;
13907                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13908                    }
13909                }
13910            }
13911
13912            // If we actually concluded any broadcasts, we might now be able
13913            // to trim the recipients' apps from our working set
13914            if (doTrim) {
13915                trimApplications();
13916                return;
13917            }
13918
13919        } finally {
13920            Binder.restoreCallingIdentity(origId);
13921        }
13922    }
13923
13924    void removeReceiverLocked(ReceiverList rl) {
13925        mRegisteredReceivers.remove(rl.receiver.asBinder());
13926        int N = rl.size();
13927        for (int i=0; i<N; i++) {
13928            mReceiverResolver.removeFilter(rl.get(i));
13929        }
13930    }
13931
13932    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13933        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13934            ProcessRecord r = mLruProcesses.get(i);
13935            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13936                try {
13937                    r.thread.dispatchPackageBroadcast(cmd, packages);
13938                } catch (RemoteException ex) {
13939                }
13940            }
13941        }
13942    }
13943
13944    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13945            int[] users) {
13946        List<ResolveInfo> receivers = null;
13947        try {
13948            HashSet<ComponentName> singleUserReceivers = null;
13949            boolean scannedFirstReceivers = false;
13950            for (int user : users) {
13951                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13952                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13953                if (user != 0 && newReceivers != null) {
13954                    // If this is not the primary user, we need to check for
13955                    // any receivers that should be filtered out.
13956                    for (int i=0; i<newReceivers.size(); i++) {
13957                        ResolveInfo ri = newReceivers.get(i);
13958                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13959                            newReceivers.remove(i);
13960                            i--;
13961                        }
13962                    }
13963                }
13964                if (newReceivers != null && newReceivers.size() == 0) {
13965                    newReceivers = null;
13966                }
13967                if (receivers == null) {
13968                    receivers = newReceivers;
13969                } else if (newReceivers != null) {
13970                    // We need to concatenate the additional receivers
13971                    // found with what we have do far.  This would be easy,
13972                    // but we also need to de-dup any receivers that are
13973                    // singleUser.
13974                    if (!scannedFirstReceivers) {
13975                        // Collect any single user receivers we had already retrieved.
13976                        scannedFirstReceivers = true;
13977                        for (int i=0; i<receivers.size(); i++) {
13978                            ResolveInfo ri = receivers.get(i);
13979                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13980                                ComponentName cn = new ComponentName(
13981                                        ri.activityInfo.packageName, ri.activityInfo.name);
13982                                if (singleUserReceivers == null) {
13983                                    singleUserReceivers = new HashSet<ComponentName>();
13984                                }
13985                                singleUserReceivers.add(cn);
13986                            }
13987                        }
13988                    }
13989                    // Add the new results to the existing results, tracking
13990                    // and de-dupping single user receivers.
13991                    for (int i=0; i<newReceivers.size(); i++) {
13992                        ResolveInfo ri = newReceivers.get(i);
13993                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13994                            ComponentName cn = new ComponentName(
13995                                    ri.activityInfo.packageName, ri.activityInfo.name);
13996                            if (singleUserReceivers == null) {
13997                                singleUserReceivers = new HashSet<ComponentName>();
13998                            }
13999                            if (!singleUserReceivers.contains(cn)) {
14000                                singleUserReceivers.add(cn);
14001                                receivers.add(ri);
14002                            }
14003                        } else {
14004                            receivers.add(ri);
14005                        }
14006                    }
14007                }
14008            }
14009        } catch (RemoteException ex) {
14010            // pm is in same process, this will never happen.
14011        }
14012        return receivers;
14013    }
14014
14015    private final int broadcastIntentLocked(ProcessRecord callerApp,
14016            String callerPackage, Intent intent, String resolvedType,
14017            IIntentReceiver resultTo, int resultCode, String resultData,
14018            Bundle map, String requiredPermission, int appOp,
14019            boolean ordered, boolean sticky, int callingPid, int callingUid,
14020            int userId) {
14021        intent = new Intent(intent);
14022
14023        // By default broadcasts do not go to stopped apps.
14024        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
14025
14026        if (DEBUG_BROADCAST_LIGHT) Slog.v(
14027            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
14028            + " ordered=" + ordered + " userid=" + userId);
14029        if ((resultTo != null) && !ordered) {
14030            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
14031        }
14032
14033        userId = handleIncomingUser(callingPid, callingUid, userId,
14034                true, false, "broadcast", callerPackage);
14035
14036        // Make sure that the user who is receiving this broadcast is started.
14037        // If not, we will just skip it.
14038
14039
14040        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
14041            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
14042                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
14043                Slog.w(TAG, "Skipping broadcast of " + intent
14044                        + ": user " + userId + " is stopped");
14045                return ActivityManager.BROADCAST_SUCCESS;
14046            }
14047        }
14048
14049        /*
14050         * Prevent non-system code (defined here to be non-persistent
14051         * processes) from sending protected broadcasts.
14052         */
14053        int callingAppId = UserHandle.getAppId(callingUid);
14054        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
14055            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
14056            || callingAppId == Process.NFC_UID || callingUid == 0) {
14057            // Always okay.
14058        } else if (callerApp == null || !callerApp.persistent) {
14059            try {
14060                if (AppGlobals.getPackageManager().isProtectedBroadcast(
14061                        intent.getAction())) {
14062                    String msg = "Permission Denial: not allowed to send broadcast "
14063                            + intent.getAction() + " from pid="
14064                            + callingPid + ", uid=" + callingUid;
14065                    Slog.w(TAG, msg);
14066                    throw new SecurityException(msg);
14067                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
14068                    // Special case for compatibility: we don't want apps to send this,
14069                    // but historically it has not been protected and apps may be using it
14070                    // to poke their own app widget.  So, instead of making it protected,
14071                    // just limit it to the caller.
14072                    if (callerApp == null) {
14073                        String msg = "Permission Denial: not allowed to send broadcast "
14074                                + intent.getAction() + " from unknown caller.";
14075                        Slog.w(TAG, msg);
14076                        throw new SecurityException(msg);
14077                    } else if (intent.getComponent() != null) {
14078                        // They are good enough to send to an explicit component...  verify
14079                        // it is being sent to the calling app.
14080                        if (!intent.getComponent().getPackageName().equals(
14081                                callerApp.info.packageName)) {
14082                            String msg = "Permission Denial: not allowed to send broadcast "
14083                                    + intent.getAction() + " to "
14084                                    + intent.getComponent().getPackageName() + " from "
14085                                    + callerApp.info.packageName;
14086                            Slog.w(TAG, msg);
14087                            throw new SecurityException(msg);
14088                        }
14089                    } else {
14090                        // Limit broadcast to their own package.
14091                        intent.setPackage(callerApp.info.packageName);
14092                    }
14093                }
14094            } catch (RemoteException e) {
14095                Slog.w(TAG, "Remote exception", e);
14096                return ActivityManager.BROADCAST_SUCCESS;
14097            }
14098        }
14099
14100        // Handle special intents: if this broadcast is from the package
14101        // manager about a package being removed, we need to remove all of
14102        // its activities from the history stack.
14103        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14104                intent.getAction());
14105        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14106                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14107                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14108                || uidRemoved) {
14109            if (checkComponentPermission(
14110                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14111                    callingPid, callingUid, -1, true)
14112                    == PackageManager.PERMISSION_GRANTED) {
14113                if (uidRemoved) {
14114                    final Bundle intentExtras = intent.getExtras();
14115                    final int uid = intentExtras != null
14116                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14117                    if (uid >= 0) {
14118                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14119                        synchronized (bs) {
14120                            bs.removeUidStatsLocked(uid);
14121                        }
14122                        mAppOpsService.uidRemoved(uid);
14123                    }
14124                } else {
14125                    // If resources are unavailable just force stop all
14126                    // those packages and flush the attribute cache as well.
14127                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14128                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14129                        if (list != null && (list.length > 0)) {
14130                            for (String pkg : list) {
14131                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14132                                        "storage unmount");
14133                            }
14134                            sendPackageBroadcastLocked(
14135                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14136                        }
14137                    } else {
14138                        Uri data = intent.getData();
14139                        String ssp;
14140                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14141                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14142                                    intent.getAction());
14143                            boolean fullUninstall = removed &&
14144                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14145                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14146                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14147                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14148                                        false, fullUninstall, userId,
14149                                        removed ? "pkg removed" : "pkg changed");
14150                            }
14151                            if (removed) {
14152                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14153                                        new String[] {ssp}, userId);
14154                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14155                                    mAppOpsService.packageRemoved(
14156                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14157
14158                                    // Remove all permissions granted from/to this package
14159                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14160                                }
14161                            }
14162                        }
14163                    }
14164                }
14165            } else {
14166                String msg = "Permission Denial: " + intent.getAction()
14167                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14168                        + ", uid=" + callingUid + ")"
14169                        + " requires "
14170                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14171                Slog.w(TAG, msg);
14172                throw new SecurityException(msg);
14173            }
14174
14175        // Special case for adding a package: by default turn on compatibility
14176        // mode.
14177        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14178            Uri data = intent.getData();
14179            String ssp;
14180            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14181                mCompatModePackages.handlePackageAddedLocked(ssp,
14182                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14183            }
14184        }
14185
14186        /*
14187         * If this is the time zone changed action, queue up a message that will reset the timezone
14188         * of all currently running processes. This message will get queued up before the broadcast
14189         * happens.
14190         */
14191        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14192            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14193        }
14194
14195        /*
14196         * If the user set the time, let all running processes know.
14197         */
14198        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14199            final int is24Hour = intent.getBooleanExtra(
14200                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14201            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14202        }
14203
14204        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14205            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14206        }
14207
14208        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14209            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14210            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14211        }
14212
14213        // Add to the sticky list if requested.
14214        if (sticky) {
14215            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14216                    callingPid, callingUid)
14217                    != PackageManager.PERMISSION_GRANTED) {
14218                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14219                        + callingPid + ", uid=" + callingUid
14220                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14221                Slog.w(TAG, msg);
14222                throw new SecurityException(msg);
14223            }
14224            if (requiredPermission != null) {
14225                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14226                        + " and enforce permission " + requiredPermission);
14227                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14228            }
14229            if (intent.getComponent() != null) {
14230                throw new SecurityException(
14231                        "Sticky broadcasts can't target a specific component");
14232            }
14233            // We use userId directly here, since the "all" target is maintained
14234            // as a separate set of sticky broadcasts.
14235            if (userId != UserHandle.USER_ALL) {
14236                // But first, if this is not a broadcast to all users, then
14237                // make sure it doesn't conflict with an existing broadcast to
14238                // all users.
14239                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14240                        UserHandle.USER_ALL);
14241                if (stickies != null) {
14242                    ArrayList<Intent> list = stickies.get(intent.getAction());
14243                    if (list != null) {
14244                        int N = list.size();
14245                        int i;
14246                        for (i=0; i<N; i++) {
14247                            if (intent.filterEquals(list.get(i))) {
14248                                throw new IllegalArgumentException(
14249                                        "Sticky broadcast " + intent + " for user "
14250                                        + userId + " conflicts with existing global broadcast");
14251                            }
14252                        }
14253                    }
14254                }
14255            }
14256            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14257            if (stickies == null) {
14258                stickies = new ArrayMap<String, ArrayList<Intent>>();
14259                mStickyBroadcasts.put(userId, stickies);
14260            }
14261            ArrayList<Intent> list = stickies.get(intent.getAction());
14262            if (list == null) {
14263                list = new ArrayList<Intent>();
14264                stickies.put(intent.getAction(), list);
14265            }
14266            int N = list.size();
14267            int i;
14268            for (i=0; i<N; i++) {
14269                if (intent.filterEquals(list.get(i))) {
14270                    // This sticky already exists, replace it.
14271                    list.set(i, new Intent(intent));
14272                    break;
14273                }
14274            }
14275            if (i >= N) {
14276                list.add(new Intent(intent));
14277            }
14278        }
14279
14280        int[] users;
14281        if (userId == UserHandle.USER_ALL) {
14282            // Caller wants broadcast to go to all started users.
14283            users = mStartedUserArray;
14284        } else {
14285            // Caller wants broadcast to go to one specific user.
14286            users = new int[] {userId};
14287        }
14288
14289        // Figure out who all will receive this broadcast.
14290        List receivers = null;
14291        List<BroadcastFilter> registeredReceivers = null;
14292        // Need to resolve the intent to interested receivers...
14293        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14294                 == 0) {
14295            receivers = collectReceiverComponents(intent, resolvedType, users);
14296        }
14297        if (intent.getComponent() == null) {
14298            registeredReceivers = mReceiverResolver.queryIntent(intent,
14299                    resolvedType, false, userId);
14300        }
14301
14302        final boolean replacePending =
14303                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14304
14305        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14306                + " replacePending=" + replacePending);
14307
14308        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14309        if (!ordered && NR > 0) {
14310            // If we are not serializing this broadcast, then send the
14311            // registered receivers separately so they don't wait for the
14312            // components to be launched.
14313            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14314            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14315                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14316                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14317                    ordered, sticky, false, userId);
14318            if (DEBUG_BROADCAST) Slog.v(
14319                    TAG, "Enqueueing parallel broadcast " + r);
14320            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14321            if (!replaced) {
14322                queue.enqueueParallelBroadcastLocked(r);
14323                queue.scheduleBroadcastsLocked();
14324            }
14325            registeredReceivers = null;
14326            NR = 0;
14327        }
14328
14329        // Merge into one list.
14330        int ir = 0;
14331        if (receivers != null) {
14332            // A special case for PACKAGE_ADDED: do not allow the package
14333            // being added to see this broadcast.  This prevents them from
14334            // using this as a back door to get run as soon as they are
14335            // installed.  Maybe in the future we want to have a special install
14336            // broadcast or such for apps, but we'd like to deliberately make
14337            // this decision.
14338            String skipPackages[] = null;
14339            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14340                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14341                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14342                Uri data = intent.getData();
14343                if (data != null) {
14344                    String pkgName = data.getSchemeSpecificPart();
14345                    if (pkgName != null) {
14346                        skipPackages = new String[] { pkgName };
14347                    }
14348                }
14349            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14350                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14351            }
14352            if (skipPackages != null && (skipPackages.length > 0)) {
14353                for (String skipPackage : skipPackages) {
14354                    if (skipPackage != null) {
14355                        int NT = receivers.size();
14356                        for (int it=0; it<NT; it++) {
14357                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14358                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14359                                receivers.remove(it);
14360                                it--;
14361                                NT--;
14362                            }
14363                        }
14364                    }
14365                }
14366            }
14367
14368            int NT = receivers != null ? receivers.size() : 0;
14369            int it = 0;
14370            ResolveInfo curt = null;
14371            BroadcastFilter curr = null;
14372            while (it < NT && ir < NR) {
14373                if (curt == null) {
14374                    curt = (ResolveInfo)receivers.get(it);
14375                }
14376                if (curr == null) {
14377                    curr = registeredReceivers.get(ir);
14378                }
14379                if (curr.getPriority() >= curt.priority) {
14380                    // Insert this broadcast record into the final list.
14381                    receivers.add(it, curr);
14382                    ir++;
14383                    curr = null;
14384                    it++;
14385                    NT++;
14386                } else {
14387                    // Skip to the next ResolveInfo in the final list.
14388                    it++;
14389                    curt = null;
14390                }
14391            }
14392        }
14393        while (ir < NR) {
14394            if (receivers == null) {
14395                receivers = new ArrayList();
14396            }
14397            receivers.add(registeredReceivers.get(ir));
14398            ir++;
14399        }
14400
14401        if ((receivers != null && receivers.size() > 0)
14402                || resultTo != null) {
14403            BroadcastQueue queue = broadcastQueueForIntent(intent);
14404            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14405                    callerPackage, callingPid, callingUid, resolvedType,
14406                    requiredPermission, appOp, receivers, resultTo, resultCode,
14407                    resultData, map, ordered, sticky, false, userId);
14408            if (DEBUG_BROADCAST) Slog.v(
14409                    TAG, "Enqueueing ordered broadcast " + r
14410                    + ": prev had " + queue.mOrderedBroadcasts.size());
14411            if (DEBUG_BROADCAST) {
14412                int seq = r.intent.getIntExtra("seq", -1);
14413                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14414            }
14415            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14416            if (!replaced) {
14417                queue.enqueueOrderedBroadcastLocked(r);
14418                queue.scheduleBroadcastsLocked();
14419            }
14420        }
14421
14422        return ActivityManager.BROADCAST_SUCCESS;
14423    }
14424
14425    final Intent verifyBroadcastLocked(Intent intent) {
14426        // Refuse possible leaked file descriptors
14427        if (intent != null && intent.hasFileDescriptors() == true) {
14428            throw new IllegalArgumentException("File descriptors passed in Intent");
14429        }
14430
14431        int flags = intent.getFlags();
14432
14433        if (!mProcessesReady) {
14434            // if the caller really truly claims to know what they're doing, go
14435            // ahead and allow the broadcast without launching any receivers
14436            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14437                intent = new Intent(intent);
14438                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14439            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14440                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14441                        + " before boot completion");
14442                throw new IllegalStateException("Cannot broadcast before boot completed");
14443            }
14444        }
14445
14446        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14447            throw new IllegalArgumentException(
14448                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14449        }
14450
14451        return intent;
14452    }
14453
14454    public final int broadcastIntent(IApplicationThread caller,
14455            Intent intent, String resolvedType, IIntentReceiver resultTo,
14456            int resultCode, String resultData, Bundle map,
14457            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14458        enforceNotIsolatedCaller("broadcastIntent");
14459        synchronized(this) {
14460            intent = verifyBroadcastLocked(intent);
14461
14462            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14463            final int callingPid = Binder.getCallingPid();
14464            final int callingUid = Binder.getCallingUid();
14465            final long origId = Binder.clearCallingIdentity();
14466            int res = broadcastIntentLocked(callerApp,
14467                    callerApp != null ? callerApp.info.packageName : null,
14468                    intent, resolvedType, resultTo,
14469                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14470                    callingPid, callingUid, userId);
14471            Binder.restoreCallingIdentity(origId);
14472            return res;
14473        }
14474    }
14475
14476    int broadcastIntentInPackage(String packageName, int uid,
14477            Intent intent, String resolvedType, IIntentReceiver resultTo,
14478            int resultCode, String resultData, Bundle map,
14479            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14480        synchronized(this) {
14481            intent = verifyBroadcastLocked(intent);
14482
14483            final long origId = Binder.clearCallingIdentity();
14484            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14485                    resultTo, resultCode, resultData, map, requiredPermission,
14486                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14487            Binder.restoreCallingIdentity(origId);
14488            return res;
14489        }
14490    }
14491
14492    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14493        // Refuse possible leaked file descriptors
14494        if (intent != null && intent.hasFileDescriptors() == true) {
14495            throw new IllegalArgumentException("File descriptors passed in Intent");
14496        }
14497
14498        userId = handleIncomingUser(Binder.getCallingPid(),
14499                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
14500
14501        synchronized(this) {
14502            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14503                    != PackageManager.PERMISSION_GRANTED) {
14504                String msg = "Permission Denial: unbroadcastIntent() from pid="
14505                        + Binder.getCallingPid()
14506                        + ", uid=" + Binder.getCallingUid()
14507                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14508                Slog.w(TAG, msg);
14509                throw new SecurityException(msg);
14510            }
14511            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14512            if (stickies != null) {
14513                ArrayList<Intent> list = stickies.get(intent.getAction());
14514                if (list != null) {
14515                    int N = list.size();
14516                    int i;
14517                    for (i=0; i<N; i++) {
14518                        if (intent.filterEquals(list.get(i))) {
14519                            list.remove(i);
14520                            break;
14521                        }
14522                    }
14523                    if (list.size() <= 0) {
14524                        stickies.remove(intent.getAction());
14525                    }
14526                }
14527                if (stickies.size() <= 0) {
14528                    mStickyBroadcasts.remove(userId);
14529                }
14530            }
14531        }
14532    }
14533
14534    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14535            String resultData, Bundle resultExtras, boolean resultAbort) {
14536        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14537        if (r == null) {
14538            Slog.w(TAG, "finishReceiver called but not found on queue");
14539            return false;
14540        }
14541
14542        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14543    }
14544
14545    void backgroundServicesFinishedLocked(int userId) {
14546        for (BroadcastQueue queue : mBroadcastQueues) {
14547            queue.backgroundServicesFinishedLocked(userId);
14548        }
14549    }
14550
14551    public void finishReceiver(IBinder who, int resultCode, String resultData,
14552            Bundle resultExtras, boolean resultAbort) {
14553        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14554
14555        // Refuse possible leaked file descriptors
14556        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14557            throw new IllegalArgumentException("File descriptors passed in Bundle");
14558        }
14559
14560        final long origId = Binder.clearCallingIdentity();
14561        try {
14562            boolean doNext = false;
14563            BroadcastRecord r;
14564
14565            synchronized(this) {
14566                r = broadcastRecordForReceiverLocked(who);
14567                if (r != null) {
14568                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14569                        resultData, resultExtras, resultAbort, true);
14570                }
14571            }
14572
14573            if (doNext) {
14574                r.queue.processNextBroadcast(false);
14575            }
14576            trimApplications();
14577        } finally {
14578            Binder.restoreCallingIdentity(origId);
14579        }
14580    }
14581
14582    // =========================================================
14583    // INSTRUMENTATION
14584    // =========================================================
14585
14586    public boolean startInstrumentation(ComponentName className,
14587            String profileFile, int flags, Bundle arguments,
14588            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14589            int userId, String abiOverride) {
14590        enforceNotIsolatedCaller("startInstrumentation");
14591        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14592                userId, false, true, "startInstrumentation", null);
14593        // Refuse possible leaked file descriptors
14594        if (arguments != null && arguments.hasFileDescriptors()) {
14595            throw new IllegalArgumentException("File descriptors passed in Bundle");
14596        }
14597
14598        synchronized(this) {
14599            InstrumentationInfo ii = null;
14600            ApplicationInfo ai = null;
14601            try {
14602                ii = mContext.getPackageManager().getInstrumentationInfo(
14603                    className, STOCK_PM_FLAGS);
14604                ai = AppGlobals.getPackageManager().getApplicationInfo(
14605                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14606            } catch (PackageManager.NameNotFoundException e) {
14607            } catch (RemoteException e) {
14608            }
14609            if (ii == null) {
14610                reportStartInstrumentationFailure(watcher, className,
14611                        "Unable to find instrumentation info for: " + className);
14612                return false;
14613            }
14614            if (ai == null) {
14615                reportStartInstrumentationFailure(watcher, className,
14616                        "Unable to find instrumentation target package: " + ii.targetPackage);
14617                return false;
14618            }
14619
14620            int match = mContext.getPackageManager().checkSignatures(
14621                    ii.targetPackage, ii.packageName);
14622            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14623                String msg = "Permission Denial: starting instrumentation "
14624                        + className + " from pid="
14625                        + Binder.getCallingPid()
14626                        + ", uid=" + Binder.getCallingPid()
14627                        + " not allowed because package " + ii.packageName
14628                        + " does not have a signature matching the target "
14629                        + ii.targetPackage;
14630                reportStartInstrumentationFailure(watcher, className, msg);
14631                throw new SecurityException(msg);
14632            }
14633
14634            final long origId = Binder.clearCallingIdentity();
14635            // Instrumentation can kill and relaunch even persistent processes
14636            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14637                    "start instr");
14638            ProcessRecord app = addAppLocked(ai, false, abiOverride);
14639            app.instrumentationClass = className;
14640            app.instrumentationInfo = ai;
14641            app.instrumentationProfileFile = profileFile;
14642            app.instrumentationArguments = arguments;
14643            app.instrumentationWatcher = watcher;
14644            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14645            app.instrumentationResultClass = className;
14646            Binder.restoreCallingIdentity(origId);
14647        }
14648
14649        return true;
14650    }
14651
14652    /**
14653     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14654     * error to the logs, but if somebody is watching, send the report there too.  This enables
14655     * the "am" command to report errors with more information.
14656     *
14657     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14658     * @param cn The component name of the instrumentation.
14659     * @param report The error report.
14660     */
14661    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14662            ComponentName cn, String report) {
14663        Slog.w(TAG, report);
14664        try {
14665            if (watcher != null) {
14666                Bundle results = new Bundle();
14667                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14668                results.putString("Error", report);
14669                watcher.instrumentationStatus(cn, -1, results);
14670            }
14671        } catch (RemoteException e) {
14672            Slog.w(TAG, e);
14673        }
14674    }
14675
14676    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14677        if (app.instrumentationWatcher != null) {
14678            try {
14679                // NOTE:  IInstrumentationWatcher *must* be oneway here
14680                app.instrumentationWatcher.instrumentationFinished(
14681                    app.instrumentationClass,
14682                    resultCode,
14683                    results);
14684            } catch (RemoteException e) {
14685            }
14686        }
14687        if (app.instrumentationUiAutomationConnection != null) {
14688            try {
14689                app.instrumentationUiAutomationConnection.shutdown();
14690            } catch (RemoteException re) {
14691                /* ignore */
14692            }
14693            // Only a UiAutomation can set this flag and now that
14694            // it is finished we make sure it is reset to its default.
14695            mUserIsMonkey = false;
14696        }
14697        app.instrumentationWatcher = null;
14698        app.instrumentationUiAutomationConnection = null;
14699        app.instrumentationClass = null;
14700        app.instrumentationInfo = null;
14701        app.instrumentationProfileFile = null;
14702        app.instrumentationArguments = null;
14703
14704        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14705                "finished inst");
14706    }
14707
14708    public void finishInstrumentation(IApplicationThread target,
14709            int resultCode, Bundle results) {
14710        int userId = UserHandle.getCallingUserId();
14711        // Refuse possible leaked file descriptors
14712        if (results != null && results.hasFileDescriptors()) {
14713            throw new IllegalArgumentException("File descriptors passed in Intent");
14714        }
14715
14716        synchronized(this) {
14717            ProcessRecord app = getRecordForAppLocked(target);
14718            if (app == null) {
14719                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14720                return;
14721            }
14722            final long origId = Binder.clearCallingIdentity();
14723            finishInstrumentationLocked(app, resultCode, results);
14724            Binder.restoreCallingIdentity(origId);
14725        }
14726    }
14727
14728    // =========================================================
14729    // CONFIGURATION
14730    // =========================================================
14731
14732    public ConfigurationInfo getDeviceConfigurationInfo() {
14733        ConfigurationInfo config = new ConfigurationInfo();
14734        synchronized (this) {
14735            config.reqTouchScreen = mConfiguration.touchscreen;
14736            config.reqKeyboardType = mConfiguration.keyboard;
14737            config.reqNavigation = mConfiguration.navigation;
14738            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14739                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14740                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14741            }
14742            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14743                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14744                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14745            }
14746            config.reqGlEsVersion = GL_ES_VERSION;
14747        }
14748        return config;
14749    }
14750
14751    ActivityStack getFocusedStack() {
14752        return mStackSupervisor.getFocusedStack();
14753    }
14754
14755    public Configuration getConfiguration() {
14756        Configuration ci;
14757        synchronized(this) {
14758            ci = new Configuration(mConfiguration);
14759        }
14760        return ci;
14761    }
14762
14763    public void updatePersistentConfiguration(Configuration values) {
14764        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14765                "updateConfiguration()");
14766        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14767                "updateConfiguration()");
14768        if (values == null) {
14769            throw new NullPointerException("Configuration must not be null");
14770        }
14771
14772        synchronized(this) {
14773            final long origId = Binder.clearCallingIdentity();
14774            updateConfigurationLocked(values, null, true, false);
14775            Binder.restoreCallingIdentity(origId);
14776        }
14777    }
14778
14779    public void updateConfiguration(Configuration values) {
14780        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14781                "updateConfiguration()");
14782
14783        synchronized(this) {
14784            if (values == null && mWindowManager != null) {
14785                // sentinel: fetch the current configuration from the window manager
14786                values = mWindowManager.computeNewConfiguration();
14787            }
14788
14789            if (mWindowManager != null) {
14790                mProcessList.applyDisplaySize(mWindowManager);
14791            }
14792
14793            final long origId = Binder.clearCallingIdentity();
14794            if (values != null) {
14795                Settings.System.clearConfiguration(values);
14796            }
14797            updateConfigurationLocked(values, null, false, false);
14798            Binder.restoreCallingIdentity(origId);
14799        }
14800    }
14801
14802    /**
14803     * Do either or both things: (1) change the current configuration, and (2)
14804     * make sure the given activity is running with the (now) current
14805     * configuration.  Returns true if the activity has been left running, or
14806     * false if <var>starting</var> is being destroyed to match the new
14807     * configuration.
14808     * @param persistent TODO
14809     */
14810    boolean updateConfigurationLocked(Configuration values,
14811            ActivityRecord starting, boolean persistent, boolean initLocale) {
14812        int changes = 0;
14813
14814        if (values != null) {
14815            Configuration newConfig = new Configuration(mConfiguration);
14816            changes = newConfig.updateFrom(values);
14817            if (changes != 0) {
14818                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14819                    Slog.i(TAG, "Updating configuration to: " + values);
14820                }
14821
14822                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14823
14824                if (values.locale != null && !initLocale) {
14825                    saveLocaleLocked(values.locale,
14826                                     !values.locale.equals(mConfiguration.locale),
14827                                     values.userSetLocale);
14828                }
14829
14830                mConfigurationSeq++;
14831                if (mConfigurationSeq <= 0) {
14832                    mConfigurationSeq = 1;
14833                }
14834                newConfig.seq = mConfigurationSeq;
14835                mConfiguration = newConfig;
14836                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14837                mUsageStatsService.noteStartConfig(newConfig);
14838
14839                final Configuration configCopy = new Configuration(mConfiguration);
14840
14841                // TODO: If our config changes, should we auto dismiss any currently
14842                // showing dialogs?
14843                mShowDialogs = shouldShowDialogs(newConfig);
14844
14845                AttributeCache ac = AttributeCache.instance();
14846                if (ac != null) {
14847                    ac.updateConfiguration(configCopy);
14848                }
14849
14850                // Make sure all resources in our process are updated
14851                // right now, so that anyone who is going to retrieve
14852                // resource values after we return will be sure to get
14853                // the new ones.  This is especially important during
14854                // boot, where the first config change needs to guarantee
14855                // all resources have that config before following boot
14856                // code is executed.
14857                mSystemThread.applyConfigurationToResources(configCopy);
14858
14859                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14860                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14861                    msg.obj = new Configuration(configCopy);
14862                    mHandler.sendMessage(msg);
14863                }
14864
14865                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14866                    ProcessRecord app = mLruProcesses.get(i);
14867                    try {
14868                        if (app.thread != null) {
14869                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14870                                    + app.processName + " new config " + mConfiguration);
14871                            app.thread.scheduleConfigurationChanged(configCopy);
14872                        }
14873                    } catch (Exception e) {
14874                    }
14875                }
14876                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14877                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14878                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14879                        | Intent.FLAG_RECEIVER_FOREGROUND);
14880                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14881                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14882                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14883                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14884                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14885                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14886                    broadcastIntentLocked(null, null, intent,
14887                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14888                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14889                }
14890            }
14891        }
14892
14893        boolean kept = true;
14894        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14895        // mainStack is null during startup.
14896        if (mainStack != null) {
14897            if (changes != 0 && starting == null) {
14898                // If the configuration changed, and the caller is not already
14899                // in the process of starting an activity, then find the top
14900                // activity to check if its configuration needs to change.
14901                starting = mainStack.topRunningActivityLocked(null);
14902            }
14903
14904            if (starting != null) {
14905                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14906                // And we need to make sure at this point that all other activities
14907                // are made visible with the correct configuration.
14908                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14909            }
14910        }
14911
14912        if (values != null && mWindowManager != null) {
14913            mWindowManager.setNewConfiguration(mConfiguration);
14914        }
14915
14916        return kept;
14917    }
14918
14919    /**
14920     * Decide based on the configuration whether we should shouw the ANR,
14921     * crash, etc dialogs.  The idea is that if there is no affordnace to
14922     * press the on-screen buttons, we shouldn't show the dialog.
14923     *
14924     * A thought: SystemUI might also want to get told about this, the Power
14925     * dialog / global actions also might want different behaviors.
14926     */
14927    private static final boolean shouldShowDialogs(Configuration config) {
14928        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14929                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14930    }
14931
14932    /**
14933     * Save the locale.  You must be inside a synchronized (this) block.
14934     */
14935    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14936        if(isDiff) {
14937            SystemProperties.set("user.language", l.getLanguage());
14938            SystemProperties.set("user.region", l.getCountry());
14939        }
14940
14941        if(isPersist) {
14942            SystemProperties.set("persist.sys.language", l.getLanguage());
14943            SystemProperties.set("persist.sys.country", l.getCountry());
14944            SystemProperties.set("persist.sys.localevar", l.getVariant());
14945        }
14946    }
14947
14948    @Override
14949    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14950        ActivityRecord srec = ActivityRecord.forToken(token);
14951        return srec != null && srec.task.affinity != null &&
14952                srec.task.affinity.equals(destAffinity);
14953    }
14954
14955    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14956            Intent resultData) {
14957
14958        synchronized (this) {
14959            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14960            if (stack != null) {
14961                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14962            }
14963            return false;
14964        }
14965    }
14966
14967    public int getLaunchedFromUid(IBinder activityToken) {
14968        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14969        if (srec == null) {
14970            return -1;
14971        }
14972        return srec.launchedFromUid;
14973    }
14974
14975    public String getLaunchedFromPackage(IBinder activityToken) {
14976        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14977        if (srec == null) {
14978            return null;
14979        }
14980        return srec.launchedFromPackage;
14981    }
14982
14983    // =========================================================
14984    // LIFETIME MANAGEMENT
14985    // =========================================================
14986
14987    // Returns which broadcast queue the app is the current [or imminent] receiver
14988    // on, or 'null' if the app is not an active broadcast recipient.
14989    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14990        BroadcastRecord r = app.curReceiver;
14991        if (r != null) {
14992            return r.queue;
14993        }
14994
14995        // It's not the current receiver, but it might be starting up to become one
14996        synchronized (this) {
14997            for (BroadcastQueue queue : mBroadcastQueues) {
14998                r = queue.mPendingBroadcast;
14999                if (r != null && r.curApp == app) {
15000                    // found it; report which queue it's in
15001                    return queue;
15002                }
15003            }
15004        }
15005
15006        return null;
15007    }
15008
15009    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
15010            boolean doingAll, long now) {
15011        if (mAdjSeq == app.adjSeq) {
15012            // This adjustment has already been computed.
15013            return app.curRawAdj;
15014        }
15015
15016        if (app.thread == null) {
15017            app.adjSeq = mAdjSeq;
15018            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15019            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15020            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
15021        }
15022
15023        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
15024        app.adjSource = null;
15025        app.adjTarget = null;
15026        app.empty = false;
15027        app.cached = false;
15028
15029        final int activitiesSize = app.activities.size();
15030
15031        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15032            // The max adjustment doesn't allow this app to be anything
15033            // below foreground, so it is not worth doing work for it.
15034            app.adjType = "fixed";
15035            app.adjSeq = mAdjSeq;
15036            app.curRawAdj = app.maxAdj;
15037            app.foregroundActivities = false;
15038            app.keeping = true;
15039            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
15040            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
15041            // System processes can do UI, and when they do we want to have
15042            // them trim their memory after the user leaves the UI.  To
15043            // facilitate this, here we need to determine whether or not it
15044            // is currently showing UI.
15045            app.systemNoUi = true;
15046            if (app == TOP_APP) {
15047                app.systemNoUi = false;
15048            } else if (activitiesSize > 0) {
15049                for (int j = 0; j < activitiesSize; j++) {
15050                    final ActivityRecord r = app.activities.get(j);
15051                    if (r.visible) {
15052                        app.systemNoUi = false;
15053                    }
15054                }
15055            }
15056            if (!app.systemNoUi) {
15057                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
15058            }
15059            return (app.curAdj=app.maxAdj);
15060        }
15061
15062        app.keeping = false;
15063        app.systemNoUi = false;
15064
15065        // Determine the importance of the process, starting with most
15066        // important to least, and assign an appropriate OOM adjustment.
15067        int adj;
15068        int schedGroup;
15069        int procState;
15070        boolean foregroundActivities = false;
15071        BroadcastQueue queue;
15072        if (app == TOP_APP) {
15073            // The last app on the list is the foreground app.
15074            adj = ProcessList.FOREGROUND_APP_ADJ;
15075            schedGroup = Process.THREAD_GROUP_DEFAULT;
15076            app.adjType = "top-activity";
15077            foregroundActivities = true;
15078            procState = ActivityManager.PROCESS_STATE_TOP;
15079        } else if (app.instrumentationClass != null) {
15080            // Don't want to kill running instrumentation.
15081            adj = ProcessList.FOREGROUND_APP_ADJ;
15082            schedGroup = Process.THREAD_GROUP_DEFAULT;
15083            app.adjType = "instrumentation";
15084            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15085        } else if ((queue = isReceivingBroadcast(app)) != null) {
15086            // An app that is currently receiving a broadcast also
15087            // counts as being in the foreground for OOM killer purposes.
15088            // It's placed in a sched group based on the nature of the
15089            // broadcast as reflected by which queue it's active in.
15090            adj = ProcessList.FOREGROUND_APP_ADJ;
15091            schedGroup = (queue == mFgBroadcastQueue)
15092                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15093            app.adjType = "broadcast";
15094            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15095        } else if (app.executingServices.size() > 0) {
15096            // An app that is currently executing a service callback also
15097            // counts as being in the foreground.
15098            adj = ProcessList.FOREGROUND_APP_ADJ;
15099            schedGroup = app.execServicesFg ?
15100                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15101            app.adjType = "exec-service";
15102            procState = ActivityManager.PROCESS_STATE_SERVICE;
15103            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15104        } else {
15105            // As far as we know the process is empty.  We may change our mind later.
15106            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15107            // At this point we don't actually know the adjustment.  Use the cached adj
15108            // value that the caller wants us to.
15109            adj = cachedAdj;
15110            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15111            app.cached = true;
15112            app.empty = true;
15113            app.adjType = "cch-empty";
15114        }
15115
15116        // Examine all activities if not already foreground.
15117        if (!foregroundActivities && activitiesSize > 0) {
15118            for (int j = 0; j < activitiesSize; j++) {
15119                final ActivityRecord r = app.activities.get(j);
15120                if (r.app != app) {
15121                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15122                            + app + "?!?");
15123                    continue;
15124                }
15125                if (r.visible) {
15126                    // App has a visible activity; only upgrade adjustment.
15127                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15128                        adj = ProcessList.VISIBLE_APP_ADJ;
15129                        app.adjType = "visible";
15130                    }
15131                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15132                        procState = ActivityManager.PROCESS_STATE_TOP;
15133                    }
15134                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15135                    app.cached = false;
15136                    app.empty = false;
15137                    foregroundActivities = true;
15138                    break;
15139                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15140                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15141                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15142                        app.adjType = "pausing";
15143                    }
15144                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15145                        procState = ActivityManager.PROCESS_STATE_TOP;
15146                    }
15147                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15148                    app.cached = false;
15149                    app.empty = false;
15150                    foregroundActivities = true;
15151                } else if (r.state == ActivityState.STOPPING) {
15152                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15153                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15154                        app.adjType = "stopping";
15155                    }
15156                    // For the process state, we will at this point consider the
15157                    // process to be cached.  It will be cached either as an activity
15158                    // or empty depending on whether the activity is finishing.  We do
15159                    // this so that we can treat the process as cached for purposes of
15160                    // memory trimming (determing current memory level, trim command to
15161                    // send to process) since there can be an arbitrary number of stopping
15162                    // processes and they should soon all go into the cached state.
15163                    if (!r.finishing) {
15164                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15165                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15166                        }
15167                    }
15168                    app.cached = false;
15169                    app.empty = false;
15170                    foregroundActivities = true;
15171                } else {
15172                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15173                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15174                        app.adjType = "cch-act";
15175                    }
15176                }
15177            }
15178        }
15179
15180        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15181            if (app.foregroundServices) {
15182                // The user is aware of this app, so make it visible.
15183                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15184                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15185                app.cached = false;
15186                app.adjType = "fg-service";
15187                schedGroup = Process.THREAD_GROUP_DEFAULT;
15188            } else if (app.forcingToForeground != null) {
15189                // The user is aware of this app, so make it visible.
15190                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15191                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15192                app.cached = false;
15193                app.adjType = "force-fg";
15194                app.adjSource = app.forcingToForeground;
15195                schedGroup = Process.THREAD_GROUP_DEFAULT;
15196            }
15197        }
15198
15199        if (app == mHeavyWeightProcess) {
15200            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15201                // We don't want to kill the current heavy-weight process.
15202                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15203                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15204                app.cached = false;
15205                app.adjType = "heavy";
15206            }
15207            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15208                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15209            }
15210        }
15211
15212        if (app == mHomeProcess) {
15213            if (adj > ProcessList.HOME_APP_ADJ) {
15214                // This process is hosting what we currently consider to be the
15215                // home app, so we don't want to let it go into the background.
15216                adj = ProcessList.HOME_APP_ADJ;
15217                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15218                app.cached = false;
15219                app.adjType = "home";
15220            }
15221            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15222                procState = ActivityManager.PROCESS_STATE_HOME;
15223            }
15224        }
15225
15226        if (app == mPreviousProcess && app.activities.size() > 0) {
15227            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15228                // This was the previous process that showed UI to the user.
15229                // We want to try to keep it around more aggressively, to give
15230                // a good experience around switching between two apps.
15231                adj = ProcessList.PREVIOUS_APP_ADJ;
15232                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15233                app.cached = false;
15234                app.adjType = "previous";
15235            }
15236            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15237                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15238            }
15239        }
15240
15241        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15242                + " reason=" + app.adjType);
15243
15244        // By default, we use the computed adjustment.  It may be changed if
15245        // there are applications dependent on our services or providers, but
15246        // this gives us a baseline and makes sure we don't get into an
15247        // infinite recursion.
15248        app.adjSeq = mAdjSeq;
15249        app.curRawAdj = adj;
15250        app.hasStartedServices = false;
15251
15252        if (mBackupTarget != null && app == mBackupTarget.app) {
15253            // If possible we want to avoid killing apps while they're being backed up
15254            if (adj > ProcessList.BACKUP_APP_ADJ) {
15255                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15256                adj = ProcessList.BACKUP_APP_ADJ;
15257                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15258                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15259                }
15260                app.adjType = "backup";
15261                app.cached = false;
15262            }
15263            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15264                procState = ActivityManager.PROCESS_STATE_BACKUP;
15265            }
15266        }
15267
15268        boolean mayBeTop = false;
15269
15270        for (int is = app.services.size()-1;
15271                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15272                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15273                        || procState > ActivityManager.PROCESS_STATE_TOP);
15274                is--) {
15275            ServiceRecord s = app.services.valueAt(is);
15276            if (s.startRequested) {
15277                app.hasStartedServices = true;
15278                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15279                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15280                }
15281                if (app.hasShownUi && app != mHomeProcess) {
15282                    // If this process has shown some UI, let it immediately
15283                    // go to the LRU list because it may be pretty heavy with
15284                    // UI stuff.  We'll tag it with a label just to help
15285                    // debug and understand what is going on.
15286                    if (adj > ProcessList.SERVICE_ADJ) {
15287                        app.adjType = "cch-started-ui-services";
15288                    }
15289                } else {
15290                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15291                        // This service has seen some activity within
15292                        // recent memory, so we will keep its process ahead
15293                        // of the background processes.
15294                        if (adj > ProcessList.SERVICE_ADJ) {
15295                            adj = ProcessList.SERVICE_ADJ;
15296                            app.adjType = "started-services";
15297                            app.cached = false;
15298                        }
15299                    }
15300                    // If we have let the service slide into the background
15301                    // state, still have some text describing what it is doing
15302                    // even though the service no longer has an impact.
15303                    if (adj > ProcessList.SERVICE_ADJ) {
15304                        app.adjType = "cch-started-services";
15305                    }
15306                }
15307                // Don't kill this process because it is doing work; it
15308                // has said it is doing work.
15309                app.keeping = true;
15310            }
15311            for (int conni = s.connections.size()-1;
15312                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15313                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15314                            || procState > ActivityManager.PROCESS_STATE_TOP);
15315                    conni--) {
15316                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15317                for (int i = 0;
15318                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15319                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15320                                || procState > ActivityManager.PROCESS_STATE_TOP);
15321                        i++) {
15322                    // XXX should compute this based on the max of
15323                    // all connected clients.
15324                    ConnectionRecord cr = clist.get(i);
15325                    if (cr.binding.client == app) {
15326                        // Binding to ourself is not interesting.
15327                        continue;
15328                    }
15329                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15330                        ProcessRecord client = cr.binding.client;
15331                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15332                                TOP_APP, doingAll, now);
15333                        int clientProcState = client.curProcState;
15334                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15335                            // If the other app is cached for any reason, for purposes here
15336                            // we are going to consider it empty.  The specific cached state
15337                            // doesn't propagate except under certain conditions.
15338                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15339                        }
15340                        String adjType = null;
15341                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15342                            // Not doing bind OOM management, so treat
15343                            // this guy more like a started service.
15344                            if (app.hasShownUi && app != mHomeProcess) {
15345                                // If this process has shown some UI, let it immediately
15346                                // go to the LRU list because it may be pretty heavy with
15347                                // UI stuff.  We'll tag it with a label just to help
15348                                // debug and understand what is going on.
15349                                if (adj > clientAdj) {
15350                                    adjType = "cch-bound-ui-services";
15351                                }
15352                                app.cached = false;
15353                                clientAdj = adj;
15354                                clientProcState = procState;
15355                            } else {
15356                                if (now >= (s.lastActivity
15357                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15358                                    // This service has not seen activity within
15359                                    // recent memory, so allow it to drop to the
15360                                    // LRU list if there is no other reason to keep
15361                                    // it around.  We'll also tag it with a label just
15362                                    // to help debug and undertand what is going on.
15363                                    if (adj > clientAdj) {
15364                                        adjType = "cch-bound-services";
15365                                    }
15366                                    clientAdj = adj;
15367                                }
15368                            }
15369                        }
15370                        if (adj > clientAdj) {
15371                            // If this process has recently shown UI, and
15372                            // the process that is binding to it is less
15373                            // important than being visible, then we don't
15374                            // care about the binding as much as we care
15375                            // about letting this process get into the LRU
15376                            // list to be killed and restarted if needed for
15377                            // memory.
15378                            if (app.hasShownUi && app != mHomeProcess
15379                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15380                                adjType = "cch-bound-ui-services";
15381                            } else {
15382                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15383                                        |Context.BIND_IMPORTANT)) != 0) {
15384                                    adj = clientAdj;
15385                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15386                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15387                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15388                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15389                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15390                                    adj = clientAdj;
15391                                } else {
15392                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15393                                        adj = ProcessList.VISIBLE_APP_ADJ;
15394                                    }
15395                                }
15396                                if (!client.cached) {
15397                                    app.cached = false;
15398                                }
15399                                if (client.keeping) {
15400                                    app.keeping = true;
15401                                }
15402                                adjType = "service";
15403                            }
15404                        }
15405                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15406                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15407                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15408                            }
15409                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15410                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15411                                    // Special handling of clients who are in the top state.
15412                                    // We *may* want to consider this process to be in the
15413                                    // top state as well, but only if there is not another
15414                                    // reason for it to be running.  Being on the top is a
15415                                    // special state, meaning you are specifically running
15416                                    // for the current top app.  If the process is already
15417                                    // running in the background for some other reason, it
15418                                    // is more important to continue considering it to be
15419                                    // in the background state.
15420                                    mayBeTop = true;
15421                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15422                                } else {
15423                                    // Special handling for above-top states (persistent
15424                                    // processes).  These should not bring the current process
15425                                    // into the top state, since they are not on top.  Instead
15426                                    // give them the best state after that.
15427                                    clientProcState =
15428                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15429                                }
15430                            }
15431                        } else {
15432                            if (clientProcState <
15433                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15434                                clientProcState =
15435                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15436                            }
15437                        }
15438                        if (procState > clientProcState) {
15439                            procState = clientProcState;
15440                        }
15441                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15442                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15443                            app.pendingUiClean = true;
15444                        }
15445                        if (adjType != null) {
15446                            app.adjType = adjType;
15447                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15448                                    .REASON_SERVICE_IN_USE;
15449                            app.adjSource = cr.binding.client;
15450                            app.adjSourceOom = clientAdj;
15451                            app.adjTarget = s.name;
15452                        }
15453                    }
15454                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15455                        app.treatLikeActivity = true;
15456                    }
15457                    final ActivityRecord a = cr.activity;
15458                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15459                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15460                                (a.visible || a.state == ActivityState.RESUMED
15461                                 || a.state == ActivityState.PAUSING)) {
15462                            adj = ProcessList.FOREGROUND_APP_ADJ;
15463                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15464                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15465                            }
15466                            app.cached = false;
15467                            app.adjType = "service";
15468                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15469                                    .REASON_SERVICE_IN_USE;
15470                            app.adjSource = a;
15471                            app.adjSourceOom = adj;
15472                            app.adjTarget = s.name;
15473                        }
15474                    }
15475                }
15476            }
15477        }
15478
15479        for (int provi = app.pubProviders.size()-1;
15480                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15481                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15482                        || procState > ActivityManager.PROCESS_STATE_TOP);
15483                provi--) {
15484            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15485            for (int i = cpr.connections.size()-1;
15486                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15487                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15488                            || procState > ActivityManager.PROCESS_STATE_TOP);
15489                    i--) {
15490                ContentProviderConnection conn = cpr.connections.get(i);
15491                ProcessRecord client = conn.client;
15492                if (client == app) {
15493                    // Being our own client is not interesting.
15494                    continue;
15495                }
15496                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15497                int clientProcState = client.curProcState;
15498                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15499                    // If the other app is cached for any reason, for purposes here
15500                    // we are going to consider it empty.
15501                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15502                }
15503                if (adj > clientAdj) {
15504                    if (app.hasShownUi && app != mHomeProcess
15505                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15506                        app.adjType = "cch-ui-provider";
15507                    } else {
15508                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15509                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15510                        app.adjType = "provider";
15511                    }
15512                    app.cached &= client.cached;
15513                    app.keeping |= client.keeping;
15514                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15515                            .REASON_PROVIDER_IN_USE;
15516                    app.adjSource = client;
15517                    app.adjSourceOom = clientAdj;
15518                    app.adjTarget = cpr.name;
15519                }
15520                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15521                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15522                        // Special handling of clients who are in the top state.
15523                        // We *may* want to consider this process to be in the
15524                        // top state as well, but only if there is not another
15525                        // reason for it to be running.  Being on the top is a
15526                        // special state, meaning you are specifically running
15527                        // for the current top app.  If the process is already
15528                        // running in the background for some other reason, it
15529                        // is more important to continue considering it to be
15530                        // in the background state.
15531                        mayBeTop = true;
15532                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15533                    } else {
15534                        // Special handling for above-top states (persistent
15535                        // processes).  These should not bring the current process
15536                        // into the top state, since they are not on top.  Instead
15537                        // give them the best state after that.
15538                        clientProcState =
15539                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15540                    }
15541                }
15542                if (procState > clientProcState) {
15543                    procState = clientProcState;
15544                }
15545                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15546                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15547                }
15548            }
15549            // If the provider has external (non-framework) process
15550            // dependencies, ensure that its adjustment is at least
15551            // FOREGROUND_APP_ADJ.
15552            if (cpr.hasExternalProcessHandles()) {
15553                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15554                    adj = ProcessList.FOREGROUND_APP_ADJ;
15555                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15556                    app.cached = false;
15557                    app.keeping = true;
15558                    app.adjType = "provider";
15559                    app.adjTarget = cpr.name;
15560                }
15561                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15562                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15563                }
15564            }
15565        }
15566
15567        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15568            // A client of one of our services or providers is in the top state.  We
15569            // *may* want to be in the top state, but not if we are already running in
15570            // the background for some other reason.  For the decision here, we are going
15571            // to pick out a few specific states that we want to remain in when a client
15572            // is top (states that tend to be longer-term) and otherwise allow it to go
15573            // to the top state.
15574            switch (procState) {
15575                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15576                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15577                case ActivityManager.PROCESS_STATE_SERVICE:
15578                    // These all are longer-term states, so pull them up to the top
15579                    // of the background states, but not all the way to the top state.
15580                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15581                    break;
15582                default:
15583                    // Otherwise, top is a better choice, so take it.
15584                    procState = ActivityManager.PROCESS_STATE_TOP;
15585                    break;
15586            }
15587        }
15588
15589        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15590            if (app.hasClientActivities) {
15591                // This is a cached process, but with client activities.  Mark it so.
15592                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15593                app.adjType = "cch-client-act";
15594            } else if (app.treatLikeActivity) {
15595                // This is a cached process, but somebody wants us to treat it like it has
15596                // an activity, okay!
15597                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15598                app.adjType = "cch-as-act";
15599            }
15600        }
15601
15602        if (adj == ProcessList.SERVICE_ADJ) {
15603            if (doingAll) {
15604                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15605                mNewNumServiceProcs++;
15606                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15607                if (!app.serviceb) {
15608                    // This service isn't far enough down on the LRU list to
15609                    // normally be a B service, but if we are low on RAM and it
15610                    // is large we want to force it down since we would prefer to
15611                    // keep launcher over it.
15612                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15613                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15614                        app.serviceHighRam = true;
15615                        app.serviceb = true;
15616                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15617                    } else {
15618                        mNewNumAServiceProcs++;
15619                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15620                    }
15621                } else {
15622                    app.serviceHighRam = false;
15623                }
15624            }
15625            if (app.serviceb) {
15626                adj = ProcessList.SERVICE_B_ADJ;
15627            }
15628        }
15629
15630        app.curRawAdj = adj;
15631
15632        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15633        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15634        if (adj > app.maxAdj) {
15635            adj = app.maxAdj;
15636            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15637                schedGroup = Process.THREAD_GROUP_DEFAULT;
15638            }
15639        }
15640        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15641            app.keeping = true;
15642        }
15643
15644        // Do final modification to adj.  Everything we do between here and applying
15645        // the final setAdj must be done in this function, because we will also use
15646        // it when computing the final cached adj later.  Note that we don't need to
15647        // worry about this for max adj above, since max adj will always be used to
15648        // keep it out of the cached vaues.
15649        app.curAdj = app.modifyRawOomAdj(adj);
15650        app.curSchedGroup = schedGroup;
15651        app.curProcState = procState;
15652        app.foregroundActivities = foregroundActivities;
15653
15654        return app.curRawAdj;
15655    }
15656
15657    /**
15658     * Schedule PSS collection of a process.
15659     */
15660    void requestPssLocked(ProcessRecord proc, int procState) {
15661        if (mPendingPssProcesses.contains(proc)) {
15662            return;
15663        }
15664        if (mPendingPssProcesses.size() == 0) {
15665            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15666        }
15667        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15668        proc.pssProcState = procState;
15669        mPendingPssProcesses.add(proc);
15670    }
15671
15672    /**
15673     * Schedule PSS collection of all processes.
15674     */
15675    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15676        if (!always) {
15677            if (now < (mLastFullPssTime +
15678                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15679                return;
15680            }
15681        }
15682        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15683        mLastFullPssTime = now;
15684        mFullPssPending = true;
15685        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15686        mPendingPssProcesses.clear();
15687        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15688            ProcessRecord app = mLruProcesses.get(i);
15689            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15690                app.pssProcState = app.setProcState;
15691                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15692                        isSleeping(), now);
15693                mPendingPssProcesses.add(app);
15694            }
15695        }
15696        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15697    }
15698
15699    /**
15700     * Ask a given process to GC right now.
15701     */
15702    final void performAppGcLocked(ProcessRecord app) {
15703        try {
15704            app.lastRequestedGc = SystemClock.uptimeMillis();
15705            if (app.thread != null) {
15706                if (app.reportLowMemory) {
15707                    app.reportLowMemory = false;
15708                    app.thread.scheduleLowMemory();
15709                } else {
15710                    app.thread.processInBackground();
15711                }
15712            }
15713        } catch (Exception e) {
15714            // whatever.
15715        }
15716    }
15717
15718    /**
15719     * Returns true if things are idle enough to perform GCs.
15720     */
15721    private final boolean canGcNowLocked() {
15722        boolean processingBroadcasts = false;
15723        for (BroadcastQueue q : mBroadcastQueues) {
15724            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15725                processingBroadcasts = true;
15726            }
15727        }
15728        return !processingBroadcasts
15729                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15730    }
15731
15732    /**
15733     * Perform GCs on all processes that are waiting for it, but only
15734     * if things are idle.
15735     */
15736    final void performAppGcsLocked() {
15737        final int N = mProcessesToGc.size();
15738        if (N <= 0) {
15739            return;
15740        }
15741        if (canGcNowLocked()) {
15742            while (mProcessesToGc.size() > 0) {
15743                ProcessRecord proc = mProcessesToGc.remove(0);
15744                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15745                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15746                            <= SystemClock.uptimeMillis()) {
15747                        // To avoid spamming the system, we will GC processes one
15748                        // at a time, waiting a few seconds between each.
15749                        performAppGcLocked(proc);
15750                        scheduleAppGcsLocked();
15751                        return;
15752                    } else {
15753                        // It hasn't been long enough since we last GCed this
15754                        // process...  put it in the list to wait for its time.
15755                        addProcessToGcListLocked(proc);
15756                        break;
15757                    }
15758                }
15759            }
15760
15761            scheduleAppGcsLocked();
15762        }
15763    }
15764
15765    /**
15766     * If all looks good, perform GCs on all processes waiting for them.
15767     */
15768    final void performAppGcsIfAppropriateLocked() {
15769        if (canGcNowLocked()) {
15770            performAppGcsLocked();
15771            return;
15772        }
15773        // Still not idle, wait some more.
15774        scheduleAppGcsLocked();
15775    }
15776
15777    /**
15778     * Schedule the execution of all pending app GCs.
15779     */
15780    final void scheduleAppGcsLocked() {
15781        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15782
15783        if (mProcessesToGc.size() > 0) {
15784            // Schedule a GC for the time to the next process.
15785            ProcessRecord proc = mProcessesToGc.get(0);
15786            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15787
15788            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15789            long now = SystemClock.uptimeMillis();
15790            if (when < (now+GC_TIMEOUT)) {
15791                when = now + GC_TIMEOUT;
15792            }
15793            mHandler.sendMessageAtTime(msg, when);
15794        }
15795    }
15796
15797    /**
15798     * Add a process to the array of processes waiting to be GCed.  Keeps the
15799     * list in sorted order by the last GC time.  The process can't already be
15800     * on the list.
15801     */
15802    final void addProcessToGcListLocked(ProcessRecord proc) {
15803        boolean added = false;
15804        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15805            if (mProcessesToGc.get(i).lastRequestedGc <
15806                    proc.lastRequestedGc) {
15807                added = true;
15808                mProcessesToGc.add(i+1, proc);
15809                break;
15810            }
15811        }
15812        if (!added) {
15813            mProcessesToGc.add(0, proc);
15814        }
15815    }
15816
15817    /**
15818     * Set up to ask a process to GC itself.  This will either do it
15819     * immediately, or put it on the list of processes to gc the next
15820     * time things are idle.
15821     */
15822    final void scheduleAppGcLocked(ProcessRecord app) {
15823        long now = SystemClock.uptimeMillis();
15824        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15825            return;
15826        }
15827        if (!mProcessesToGc.contains(app)) {
15828            addProcessToGcListLocked(app);
15829            scheduleAppGcsLocked();
15830        }
15831    }
15832
15833    final void checkExcessivePowerUsageLocked(boolean doKills) {
15834        updateCpuStatsNow();
15835
15836        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15837        boolean doWakeKills = doKills;
15838        boolean doCpuKills = doKills;
15839        if (mLastPowerCheckRealtime == 0) {
15840            doWakeKills = false;
15841        }
15842        if (mLastPowerCheckUptime == 0) {
15843            doCpuKills = false;
15844        }
15845        if (stats.isScreenOn()) {
15846            doWakeKills = false;
15847        }
15848        final long curRealtime = SystemClock.elapsedRealtime();
15849        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15850        final long curUptime = SystemClock.uptimeMillis();
15851        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15852        mLastPowerCheckRealtime = curRealtime;
15853        mLastPowerCheckUptime = curUptime;
15854        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15855            doWakeKills = false;
15856        }
15857        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15858            doCpuKills = false;
15859        }
15860        int i = mLruProcesses.size();
15861        while (i > 0) {
15862            i--;
15863            ProcessRecord app = mLruProcesses.get(i);
15864            if (!app.keeping) {
15865                long wtime;
15866                synchronized (stats) {
15867                    wtime = stats.getProcessWakeTime(app.info.uid,
15868                            app.pid, curRealtime);
15869                }
15870                long wtimeUsed = wtime - app.lastWakeTime;
15871                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15872                if (DEBUG_POWER) {
15873                    StringBuilder sb = new StringBuilder(128);
15874                    sb.append("Wake for ");
15875                    app.toShortString(sb);
15876                    sb.append(": over ");
15877                    TimeUtils.formatDuration(realtimeSince, sb);
15878                    sb.append(" used ");
15879                    TimeUtils.formatDuration(wtimeUsed, sb);
15880                    sb.append(" (");
15881                    sb.append((wtimeUsed*100)/realtimeSince);
15882                    sb.append("%)");
15883                    Slog.i(TAG, sb.toString());
15884                    sb.setLength(0);
15885                    sb.append("CPU for ");
15886                    app.toShortString(sb);
15887                    sb.append(": over ");
15888                    TimeUtils.formatDuration(uptimeSince, sb);
15889                    sb.append(" used ");
15890                    TimeUtils.formatDuration(cputimeUsed, sb);
15891                    sb.append(" (");
15892                    sb.append((cputimeUsed*100)/uptimeSince);
15893                    sb.append("%)");
15894                    Slog.i(TAG, sb.toString());
15895                }
15896                // If a process has held a wake lock for more
15897                // than 50% of the time during this period,
15898                // that sounds bad.  Kill!
15899                if (doWakeKills && realtimeSince > 0
15900                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15901                    synchronized (stats) {
15902                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15903                                realtimeSince, wtimeUsed);
15904                    }
15905                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15906                            + " during " + realtimeSince);
15907                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15908                } else if (doCpuKills && uptimeSince > 0
15909                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15910                    synchronized (stats) {
15911                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15912                                uptimeSince, cputimeUsed);
15913                    }
15914                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15915                            + " during " + uptimeSince);
15916                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15917                } else {
15918                    app.lastWakeTime = wtime;
15919                    app.lastCpuTime = app.curCpuTime;
15920                }
15921            }
15922        }
15923    }
15924
15925    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15926            ProcessRecord TOP_APP, boolean doingAll, long now) {
15927        boolean success = true;
15928
15929        if (app.curRawAdj != app.setRawAdj) {
15930            if (wasKeeping && !app.keeping) {
15931                // This app is no longer something we want to keep.  Note
15932                // its current wake lock time to later know to kill it if
15933                // it is not behaving well.
15934                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15935                synchronized (stats) {
15936                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15937                            app.pid, SystemClock.elapsedRealtime());
15938                }
15939                app.lastCpuTime = app.curCpuTime;
15940            }
15941
15942            app.setRawAdj = app.curRawAdj;
15943        }
15944
15945        int changes = 0;
15946
15947        if (app.curAdj != app.setAdj) {
15948            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
15949            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15950                TAG, "Set " + app.pid + " " + app.processName +
15951                " adj " + app.curAdj + ": " + app.adjType);
15952            app.setAdj = app.curAdj;
15953        }
15954
15955        if (app.setSchedGroup != app.curSchedGroup) {
15956            app.setSchedGroup = app.curSchedGroup;
15957            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15958                    "Setting process group of " + app.processName
15959                    + " to " + app.curSchedGroup);
15960            if (app.waitingToKill != null &&
15961                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15962                killUnneededProcessLocked(app, app.waitingToKill);
15963                success = false;
15964            } else {
15965                if (true) {
15966                    long oldId = Binder.clearCallingIdentity();
15967                    try {
15968                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15969                    } catch (Exception e) {
15970                        Slog.w(TAG, "Failed setting process group of " + app.pid
15971                                + " to " + app.curSchedGroup);
15972                        e.printStackTrace();
15973                    } finally {
15974                        Binder.restoreCallingIdentity(oldId);
15975                    }
15976                } else {
15977                    if (app.thread != null) {
15978                        try {
15979                            app.thread.setSchedulingGroup(app.curSchedGroup);
15980                        } catch (RemoteException e) {
15981                        }
15982                    }
15983                }
15984                Process.setSwappiness(app.pid,
15985                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15986            }
15987        }
15988        if (app.repForegroundActivities != app.foregroundActivities) {
15989            app.repForegroundActivities = app.foregroundActivities;
15990            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15991        }
15992        if (app.repProcState != app.curProcState) {
15993            app.repProcState = app.curProcState;
15994            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
15995            if (app.thread != null) {
15996                try {
15997                    if (false) {
15998                        //RuntimeException h = new RuntimeException("here");
15999                        Slog.i(TAG, "Sending new process state " + app.repProcState
16000                                + " to " + app /*, h*/);
16001                    }
16002                    app.thread.setProcessState(app.repProcState);
16003                } catch (RemoteException e) {
16004                }
16005            }
16006        }
16007        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
16008                app.setProcState)) {
16009            app.lastStateTime = now;
16010            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16011                    isSleeping(), now);
16012            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
16013                    + ProcessList.makeProcStateString(app.setProcState) + " to "
16014                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
16015                    + (app.nextPssTime-now) + ": " + app);
16016        } else {
16017            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
16018                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
16019                requestPssLocked(app, app.setProcState);
16020                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
16021                        isSleeping(), now);
16022            } else if (false && DEBUG_PSS) {
16023                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
16024            }
16025        }
16026        if (app.setProcState != app.curProcState) {
16027            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16028                    "Proc state change of " + app.processName
16029                    + " to " + app.curProcState);
16030            app.setProcState = app.curProcState;
16031            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16032                app.notCachedSinceIdle = false;
16033            }
16034            if (!doingAll) {
16035                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
16036            } else {
16037                app.procStateChanged = true;
16038            }
16039        }
16040
16041        if (changes != 0) {
16042            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
16043            int i = mPendingProcessChanges.size()-1;
16044            ProcessChangeItem item = null;
16045            while (i >= 0) {
16046                item = mPendingProcessChanges.get(i);
16047                if (item.pid == app.pid) {
16048                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
16049                    break;
16050                }
16051                i--;
16052            }
16053            if (i < 0) {
16054                // No existing item in pending changes; need a new one.
16055                final int NA = mAvailProcessChanges.size();
16056                if (NA > 0) {
16057                    item = mAvailProcessChanges.remove(NA-1);
16058                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
16059                } else {
16060                    item = new ProcessChangeItem();
16061                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
16062                }
16063                item.changes = 0;
16064                item.pid = app.pid;
16065                item.uid = app.info.uid;
16066                if (mPendingProcessChanges.size() == 0) {
16067                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
16068                            "*** Enqueueing dispatch processes changed!");
16069                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
16070                }
16071                mPendingProcessChanges.add(item);
16072            }
16073            item.changes |= changes;
16074            item.processState = app.repProcState;
16075            item.foregroundActivities = app.repForegroundActivities;
16076            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16077                    + Integer.toHexString(System.identityHashCode(item))
16078                    + " " + app.toShortString() + ": changes=" + item.changes
16079                    + " procState=" + item.processState
16080                    + " foreground=" + item.foregroundActivities
16081                    + " type=" + app.adjType + " source=" + app.adjSource
16082                    + " target=" + app.adjTarget);
16083        }
16084
16085        return success;
16086    }
16087
16088    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
16089        if (proc.thread != null) {
16090            if (proc.baseProcessTracker != null) {
16091                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16092            }
16093            if (proc.repProcState >= 0) {
16094                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
16095                        proc.repProcState);
16096            }
16097        }
16098    }
16099
16100    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16101            ProcessRecord TOP_APP, boolean doingAll, long now) {
16102        if (app.thread == null) {
16103            return false;
16104        }
16105
16106        final boolean wasKeeping = app.keeping;
16107
16108        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16109
16110        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now);
16111    }
16112
16113    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16114            boolean oomAdj) {
16115        if (isForeground != proc.foregroundServices) {
16116            proc.foregroundServices = isForeground;
16117            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16118                    proc.info.uid);
16119            if (isForeground) {
16120                if (curProcs == null) {
16121                    curProcs = new ArrayList<ProcessRecord>();
16122                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16123                }
16124                if (!curProcs.contains(proc)) {
16125                    curProcs.add(proc);
16126                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16127                            proc.info.packageName, proc.info.uid);
16128                }
16129            } else {
16130                if (curProcs != null) {
16131                    if (curProcs.remove(proc)) {
16132                        mBatteryStatsService.noteEvent(
16133                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16134                                proc.info.packageName, proc.info.uid);
16135                        if (curProcs.size() <= 0) {
16136                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16137                        }
16138                    }
16139                }
16140            }
16141            if (oomAdj) {
16142                updateOomAdjLocked();
16143            }
16144        }
16145    }
16146
16147    private final ActivityRecord resumedAppLocked() {
16148        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16149        String pkg;
16150        int uid;
16151        if (act != null) {
16152            pkg = act.packageName;
16153            uid = act.info.applicationInfo.uid;
16154        } else {
16155            pkg = null;
16156            uid = -1;
16157        }
16158        // Has the UID or resumed package name changed?
16159        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16160                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16161            if (mCurResumedPackage != null) {
16162                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16163                        mCurResumedPackage, mCurResumedUid);
16164            }
16165            mCurResumedPackage = pkg;
16166            mCurResumedUid = uid;
16167            if (mCurResumedPackage != null) {
16168                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16169                        mCurResumedPackage, mCurResumedUid);
16170            }
16171        }
16172        return act;
16173    }
16174
16175    final boolean updateOomAdjLocked(ProcessRecord app) {
16176        final ActivityRecord TOP_ACT = resumedAppLocked();
16177        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16178        final boolean wasCached = app.cached;
16179
16180        mAdjSeq++;
16181
16182        // This is the desired cached adjusment we want to tell it to use.
16183        // If our app is currently cached, we know it, and that is it.  Otherwise,
16184        // we don't know it yet, and it needs to now be cached we will then
16185        // need to do a complete oom adj.
16186        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16187                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16188        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16189                SystemClock.uptimeMillis());
16190        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16191            // Changed to/from cached state, so apps after it in the LRU
16192            // list may also be changed.
16193            updateOomAdjLocked();
16194        }
16195        return success;
16196    }
16197
16198    final void updateOomAdjLocked() {
16199        final ActivityRecord TOP_ACT = resumedAppLocked();
16200        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16201        final long now = SystemClock.uptimeMillis();
16202        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16203        final int N = mLruProcesses.size();
16204
16205        if (false) {
16206            RuntimeException e = new RuntimeException();
16207            e.fillInStackTrace();
16208            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16209        }
16210
16211        mAdjSeq++;
16212        mNewNumServiceProcs = 0;
16213        mNewNumAServiceProcs = 0;
16214
16215        final int emptyProcessLimit;
16216        final int cachedProcessLimit;
16217        if (mProcessLimit <= 0) {
16218            emptyProcessLimit = cachedProcessLimit = 0;
16219        } else if (mProcessLimit == 1) {
16220            emptyProcessLimit = 1;
16221            cachedProcessLimit = 0;
16222        } else {
16223            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16224            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16225        }
16226
16227        // Let's determine how many processes we have running vs.
16228        // how many slots we have for background processes; we may want
16229        // to put multiple processes in a slot of there are enough of
16230        // them.
16231        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16232                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16233        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16234        if (numEmptyProcs > cachedProcessLimit) {
16235            // If there are more empty processes than our limit on cached
16236            // processes, then use the cached process limit for the factor.
16237            // This ensures that the really old empty processes get pushed
16238            // down to the bottom, so if we are running low on memory we will
16239            // have a better chance at keeping around more cached processes
16240            // instead of a gazillion empty processes.
16241            numEmptyProcs = cachedProcessLimit;
16242        }
16243        int emptyFactor = numEmptyProcs/numSlots;
16244        if (emptyFactor < 1) emptyFactor = 1;
16245        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16246        if (cachedFactor < 1) cachedFactor = 1;
16247        int stepCached = 0;
16248        int stepEmpty = 0;
16249        int numCached = 0;
16250        int numEmpty = 0;
16251        int numTrimming = 0;
16252
16253        mNumNonCachedProcs = 0;
16254        mNumCachedHiddenProcs = 0;
16255
16256        // First update the OOM adjustment for each of the
16257        // application processes based on their current state.
16258        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16259        int nextCachedAdj = curCachedAdj+1;
16260        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16261        int nextEmptyAdj = curEmptyAdj+2;
16262        for (int i=N-1; i>=0; i--) {
16263            ProcessRecord app = mLruProcesses.get(i);
16264            if (!app.killedByAm && app.thread != null) {
16265                app.procStateChanged = false;
16266                final boolean wasKeeping = app.keeping;
16267                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16268
16269                // If we haven't yet assigned the final cached adj
16270                // to the process, do that now.
16271                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16272                    switch (app.curProcState) {
16273                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16274                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16275                            // This process is a cached process holding activities...
16276                            // assign it the next cached value for that type, and then
16277                            // step that cached level.
16278                            app.curRawAdj = curCachedAdj;
16279                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16280                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16281                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16282                                    + ")");
16283                            if (curCachedAdj != nextCachedAdj) {
16284                                stepCached++;
16285                                if (stepCached >= cachedFactor) {
16286                                    stepCached = 0;
16287                                    curCachedAdj = nextCachedAdj;
16288                                    nextCachedAdj += 2;
16289                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16290                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16291                                    }
16292                                }
16293                            }
16294                            break;
16295                        default:
16296                            // For everything else, assign next empty cached process
16297                            // level and bump that up.  Note that this means that
16298                            // long-running services that have dropped down to the
16299                            // cached level will be treated as empty (since their process
16300                            // state is still as a service), which is what we want.
16301                            app.curRawAdj = curEmptyAdj;
16302                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16303                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16304                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16305                                    + ")");
16306                            if (curEmptyAdj != nextEmptyAdj) {
16307                                stepEmpty++;
16308                                if (stepEmpty >= emptyFactor) {
16309                                    stepEmpty = 0;
16310                                    curEmptyAdj = nextEmptyAdj;
16311                                    nextEmptyAdj += 2;
16312                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16313                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16314                                    }
16315                                }
16316                            }
16317                            break;
16318                    }
16319                }
16320
16321                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now);
16322
16323                // Count the number of process types.
16324                switch (app.curProcState) {
16325                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16326                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16327                        mNumCachedHiddenProcs++;
16328                        numCached++;
16329                        if (numCached > cachedProcessLimit) {
16330                            killUnneededProcessLocked(app, "cached #" + numCached);
16331                        }
16332                        break;
16333                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16334                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16335                                && app.lastActivityTime < oldTime) {
16336                            killUnneededProcessLocked(app, "empty for "
16337                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16338                                    / 1000) + "s");
16339                        } else {
16340                            numEmpty++;
16341                            if (numEmpty > emptyProcessLimit) {
16342                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16343                            }
16344                        }
16345                        break;
16346                    default:
16347                        mNumNonCachedProcs++;
16348                        break;
16349                }
16350
16351                if (app.isolated && app.services.size() <= 0) {
16352                    // If this is an isolated process, and there are no
16353                    // services running in it, then the process is no longer
16354                    // needed.  We agressively kill these because we can by
16355                    // definition not re-use the same process again, and it is
16356                    // good to avoid having whatever code was running in them
16357                    // left sitting around after no longer needed.
16358                    killUnneededProcessLocked(app, "isolated not needed");
16359                }
16360
16361                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16362                        && !app.killedByAm) {
16363                    numTrimming++;
16364                }
16365            }
16366        }
16367
16368        mNumServiceProcs = mNewNumServiceProcs;
16369
16370        // Now determine the memory trimming level of background processes.
16371        // Unfortunately we need to start at the back of the list to do this
16372        // properly.  We only do this if the number of background apps we
16373        // are managing to keep around is less than half the maximum we desire;
16374        // if we are keeping a good number around, we'll let them use whatever
16375        // memory they want.
16376        final int numCachedAndEmpty = numCached + numEmpty;
16377        int memFactor;
16378        if (numCached <= ProcessList.TRIM_CACHED_APPS
16379                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16380            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16381                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16382            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16383                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16384            } else {
16385                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16386            }
16387        } else {
16388            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16389        }
16390        // We always allow the memory level to go up (better).  We only allow it to go
16391        // down if we are in a state where that is allowed, *and* the total number of processes
16392        // has gone down since last time.
16393        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16394                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16395                + " last=" + mLastNumProcesses);
16396        if (memFactor > mLastMemoryLevel) {
16397            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16398                memFactor = mLastMemoryLevel;
16399                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16400            }
16401        }
16402        mLastMemoryLevel = memFactor;
16403        mLastNumProcesses = mLruProcesses.size();
16404        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16405        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16406        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16407            if (mLowRamStartTime == 0) {
16408                mLowRamStartTime = now;
16409            }
16410            int step = 0;
16411            int fgTrimLevel;
16412            switch (memFactor) {
16413                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16414                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16415                    break;
16416                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16417                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16418                    break;
16419                default:
16420                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16421                    break;
16422            }
16423            int factor = numTrimming/3;
16424            int minFactor = 2;
16425            if (mHomeProcess != null) minFactor++;
16426            if (mPreviousProcess != null) minFactor++;
16427            if (factor < minFactor) factor = minFactor;
16428            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16429            for (int i=N-1; i>=0; i--) {
16430                ProcessRecord app = mLruProcesses.get(i);
16431                if (allChanged || app.procStateChanged) {
16432                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16433                    app.procStateChanged = false;
16434                }
16435                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16436                        && !app.killedByAm) {
16437                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16438                        try {
16439                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16440                                    "Trimming memory of " + app.processName
16441                                    + " to " + curLevel);
16442                            app.thread.scheduleTrimMemory(curLevel);
16443                        } catch (RemoteException e) {
16444                        }
16445                        if (false) {
16446                            // For now we won't do this; our memory trimming seems
16447                            // to be good enough at this point that destroying
16448                            // activities causes more harm than good.
16449                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16450                                    && app != mHomeProcess && app != mPreviousProcess) {
16451                                // Need to do this on its own message because the stack may not
16452                                // be in a consistent state at this point.
16453                                // For these apps we will also finish their activities
16454                                // to help them free memory.
16455                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16456                            }
16457                        }
16458                    }
16459                    app.trimMemoryLevel = curLevel;
16460                    step++;
16461                    if (step >= factor) {
16462                        step = 0;
16463                        switch (curLevel) {
16464                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16465                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16466                                break;
16467                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16468                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16469                                break;
16470                        }
16471                    }
16472                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16473                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16474                            && app.thread != null) {
16475                        try {
16476                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16477                                    "Trimming memory of heavy-weight " + app.processName
16478                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16479                            app.thread.scheduleTrimMemory(
16480                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16481                        } catch (RemoteException e) {
16482                        }
16483                    }
16484                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16485                } else {
16486                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16487                            || app.systemNoUi) && app.pendingUiClean) {
16488                        // If this application is now in the background and it
16489                        // had done UI, then give it the special trim level to
16490                        // have it free UI resources.
16491                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16492                        if (app.trimMemoryLevel < level && app.thread != null) {
16493                            try {
16494                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16495                                        "Trimming memory of bg-ui " + app.processName
16496                                        + " to " + level);
16497                                app.thread.scheduleTrimMemory(level);
16498                            } catch (RemoteException e) {
16499                            }
16500                        }
16501                        app.pendingUiClean = false;
16502                    }
16503                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16504                        try {
16505                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16506                                    "Trimming memory of fg " + app.processName
16507                                    + " to " + fgTrimLevel);
16508                            app.thread.scheduleTrimMemory(fgTrimLevel);
16509                        } catch (RemoteException e) {
16510                        }
16511                    }
16512                    app.trimMemoryLevel = fgTrimLevel;
16513                }
16514            }
16515        } else {
16516            if (mLowRamStartTime != 0) {
16517                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16518                mLowRamStartTime = 0;
16519            }
16520            for (int i=N-1; i>=0; i--) {
16521                ProcessRecord app = mLruProcesses.get(i);
16522                if (allChanged || app.procStateChanged) {
16523                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16524                    app.procStateChanged = false;
16525                }
16526                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16527                        || app.systemNoUi) && app.pendingUiClean) {
16528                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16529                            && app.thread != null) {
16530                        try {
16531                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16532                                    "Trimming memory of ui hidden " + app.processName
16533                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16534                            app.thread.scheduleTrimMemory(
16535                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16536                        } catch (RemoteException e) {
16537                        }
16538                    }
16539                    app.pendingUiClean = false;
16540                }
16541                app.trimMemoryLevel = 0;
16542            }
16543        }
16544
16545        if (mAlwaysFinishActivities) {
16546            // Need to do this on its own message because the stack may not
16547            // be in a consistent state at this point.
16548            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16549        }
16550
16551        if (allChanged) {
16552            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16553        }
16554
16555        if (mProcessStats.shouldWriteNowLocked(now)) {
16556            mHandler.post(new Runnable() {
16557                @Override public void run() {
16558                    synchronized (ActivityManagerService.this) {
16559                        mProcessStats.writeStateAsyncLocked();
16560                    }
16561                }
16562            });
16563        }
16564
16565        if (DEBUG_OOM_ADJ) {
16566            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16567        }
16568    }
16569
16570    final void trimApplications() {
16571        synchronized (this) {
16572            int i;
16573
16574            // First remove any unused application processes whose package
16575            // has been removed.
16576            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16577                final ProcessRecord app = mRemovedProcesses.get(i);
16578                if (app.activities.size() == 0
16579                        && app.curReceiver == null && app.services.size() == 0) {
16580                    Slog.i(
16581                        TAG, "Exiting empty application process "
16582                        + app.processName + " ("
16583                        + (app.thread != null ? app.thread.asBinder() : null)
16584                        + ")\n");
16585                    if (app.pid > 0 && app.pid != MY_PID) {
16586                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16587                                app.processName, app.setAdj, "empty");
16588                        app.killedByAm = true;
16589                        Process.killProcessQuiet(app.pid);
16590                    } else {
16591                        try {
16592                            app.thread.scheduleExit();
16593                        } catch (Exception e) {
16594                            // Ignore exceptions.
16595                        }
16596                    }
16597                    cleanUpApplicationRecordLocked(app, false, true, -1);
16598                    mRemovedProcesses.remove(i);
16599
16600                    if (app.persistent) {
16601                        addAppLocked(app.info, false, null /* ABI override */);
16602                    }
16603                }
16604            }
16605
16606            // Now update the oom adj for all processes.
16607            updateOomAdjLocked();
16608        }
16609    }
16610
16611    /** This method sends the specified signal to each of the persistent apps */
16612    public void signalPersistentProcesses(int sig) throws RemoteException {
16613        if (sig != Process.SIGNAL_USR1) {
16614            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16615        }
16616
16617        synchronized (this) {
16618            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16619                    != PackageManager.PERMISSION_GRANTED) {
16620                throw new SecurityException("Requires permission "
16621                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16622            }
16623
16624            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16625                ProcessRecord r = mLruProcesses.get(i);
16626                if (r.thread != null && r.persistent) {
16627                    Process.sendSignal(r.pid, sig);
16628                }
16629            }
16630        }
16631    }
16632
16633    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16634        if (proc == null || proc == mProfileProc) {
16635            proc = mProfileProc;
16636            path = mProfileFile;
16637            profileType = mProfileType;
16638            clearProfilerLocked();
16639        }
16640        if (proc == null) {
16641            return;
16642        }
16643        try {
16644            proc.thread.profilerControl(false, path, null, profileType);
16645        } catch (RemoteException e) {
16646            throw new IllegalStateException("Process disappeared");
16647        }
16648    }
16649
16650    private void clearProfilerLocked() {
16651        if (mProfileFd != null) {
16652            try {
16653                mProfileFd.close();
16654            } catch (IOException e) {
16655            }
16656        }
16657        mProfileApp = null;
16658        mProfileProc = null;
16659        mProfileFile = null;
16660        mProfileType = 0;
16661        mAutoStopProfiler = false;
16662    }
16663
16664    public boolean profileControl(String process, int userId, boolean start,
16665            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16666
16667        try {
16668            synchronized (this) {
16669                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16670                // its own permission.
16671                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16672                        != PackageManager.PERMISSION_GRANTED) {
16673                    throw new SecurityException("Requires permission "
16674                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16675                }
16676
16677                if (start && fd == null) {
16678                    throw new IllegalArgumentException("null fd");
16679                }
16680
16681                ProcessRecord proc = null;
16682                if (process != null) {
16683                    proc = findProcessLocked(process, userId, "profileControl");
16684                }
16685
16686                if (start && (proc == null || proc.thread == null)) {
16687                    throw new IllegalArgumentException("Unknown process: " + process);
16688                }
16689
16690                if (start) {
16691                    stopProfilerLocked(null, null, 0);
16692                    setProfileApp(proc.info, proc.processName, path, fd, false);
16693                    mProfileProc = proc;
16694                    mProfileType = profileType;
16695                    try {
16696                        fd = fd.dup();
16697                    } catch (IOException e) {
16698                        fd = null;
16699                    }
16700                    proc.thread.profilerControl(start, path, fd, profileType);
16701                    fd = null;
16702                    mProfileFd = null;
16703                } else {
16704                    stopProfilerLocked(proc, path, profileType);
16705                    if (fd != null) {
16706                        try {
16707                            fd.close();
16708                        } catch (IOException e) {
16709                        }
16710                    }
16711                }
16712
16713                return true;
16714            }
16715        } catch (RemoteException e) {
16716            throw new IllegalStateException("Process disappeared");
16717        } finally {
16718            if (fd != null) {
16719                try {
16720                    fd.close();
16721                } catch (IOException e) {
16722                }
16723            }
16724        }
16725    }
16726
16727    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16728        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16729                userId, true, true, callName, null);
16730        ProcessRecord proc = null;
16731        try {
16732            int pid = Integer.parseInt(process);
16733            synchronized (mPidsSelfLocked) {
16734                proc = mPidsSelfLocked.get(pid);
16735            }
16736        } catch (NumberFormatException e) {
16737        }
16738
16739        if (proc == null) {
16740            ArrayMap<String, SparseArray<ProcessRecord>> all
16741                    = mProcessNames.getMap();
16742            SparseArray<ProcessRecord> procs = all.get(process);
16743            if (procs != null && procs.size() > 0) {
16744                proc = procs.valueAt(0);
16745                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16746                    for (int i=1; i<procs.size(); i++) {
16747                        ProcessRecord thisProc = procs.valueAt(i);
16748                        if (thisProc.userId == userId) {
16749                            proc = thisProc;
16750                            break;
16751                        }
16752                    }
16753                }
16754            }
16755        }
16756
16757        return proc;
16758    }
16759
16760    public boolean dumpHeap(String process, int userId, boolean managed,
16761            String path, ParcelFileDescriptor fd) throws RemoteException {
16762
16763        try {
16764            synchronized (this) {
16765                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16766                // its own permission (same as profileControl).
16767                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16768                        != PackageManager.PERMISSION_GRANTED) {
16769                    throw new SecurityException("Requires permission "
16770                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16771                }
16772
16773                if (fd == null) {
16774                    throw new IllegalArgumentException("null fd");
16775                }
16776
16777                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16778                if (proc == null || proc.thread == null) {
16779                    throw new IllegalArgumentException("Unknown process: " + process);
16780                }
16781
16782                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16783                if (!isDebuggable) {
16784                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16785                        throw new SecurityException("Process not debuggable: " + proc);
16786                    }
16787                }
16788
16789                proc.thread.dumpHeap(managed, path, fd);
16790                fd = null;
16791                return true;
16792            }
16793        } catch (RemoteException e) {
16794            throw new IllegalStateException("Process disappeared");
16795        } finally {
16796            if (fd != null) {
16797                try {
16798                    fd.close();
16799                } catch (IOException e) {
16800                }
16801            }
16802        }
16803    }
16804
16805    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16806    public void monitor() {
16807        synchronized (this) { }
16808    }
16809
16810    void onCoreSettingsChange(Bundle settings) {
16811        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16812            ProcessRecord processRecord = mLruProcesses.get(i);
16813            try {
16814                if (processRecord.thread != null) {
16815                    processRecord.thread.setCoreSettings(settings);
16816                }
16817            } catch (RemoteException re) {
16818                /* ignore */
16819            }
16820        }
16821    }
16822
16823    // Multi-user methods
16824
16825    /**
16826     * Start user, if its not already running, but don't bring it to foreground.
16827     */
16828    @Override
16829    public boolean startUserInBackground(final int userId) {
16830        return startUser(userId, /* foreground */ false);
16831    }
16832
16833    /**
16834     * Refreshes the list of users related to the current user when either a
16835     * user switch happens or when a new related user is started in the
16836     * background.
16837     */
16838    private void updateCurrentProfileIdsLocked() {
16839        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16840                mCurrentUserId, false /* enabledOnly */);
16841        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16842        for (int i = 0; i < currentProfileIds.length; i++) {
16843            currentProfileIds[i] = profiles.get(i).id;
16844        }
16845        mCurrentProfileIds = currentProfileIds;
16846    }
16847
16848    private Set getProfileIdsLocked(int userId) {
16849        Set userIds = new HashSet<Integer>();
16850        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16851                userId, false /* enabledOnly */);
16852        for (UserInfo user : profiles) {
16853            userIds.add(Integer.valueOf(user.id));
16854        }
16855        return userIds;
16856    }
16857
16858    @Override
16859    public boolean switchUser(final int userId) {
16860        return startUser(userId, /* foregound */ true);
16861    }
16862
16863    private boolean startUser(final int userId, boolean foreground) {
16864        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
16865                != PackageManager.PERMISSION_GRANTED) {
16866            String msg = "Permission Denial: switchUser() from pid="
16867                    + Binder.getCallingPid()
16868                    + ", uid=" + Binder.getCallingUid()
16869                    + " requires " + INTERACT_ACROSS_USERS_FULL;
16870            Slog.w(TAG, msg);
16871            throw new SecurityException(msg);
16872        }
16873
16874        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16875
16876        final long ident = Binder.clearCallingIdentity();
16877        try {
16878            synchronized (this) {
16879                final int oldUserId = mCurrentUserId;
16880                if (oldUserId == userId) {
16881                    return true;
16882                }
16883
16884                mStackSupervisor.setLockTaskModeLocked(null, false);
16885
16886                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16887                if (userInfo == null) {
16888                    Slog.w(TAG, "No user info for user #" + userId);
16889                    return false;
16890                }
16891
16892                if (foreground) {
16893                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16894                            R.anim.screen_user_enter);
16895                }
16896
16897                boolean needStart = false;
16898
16899                // If the user we are switching to is not currently started, then
16900                // we need to start it now.
16901                if (mStartedUsers.get(userId) == null) {
16902                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16903                    updateStartedUserArrayLocked();
16904                    needStart = true;
16905                }
16906
16907                final Integer userIdInt = Integer.valueOf(userId);
16908                mUserLru.remove(userIdInt);
16909                mUserLru.add(userIdInt);
16910
16911                if (foreground) {
16912                    mCurrentUserId = userId;
16913                    updateCurrentProfileIdsLocked();
16914                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16915                    // Once the internal notion of the active user has switched, we lock the device
16916                    // with the option to show the user switcher on the keyguard.
16917                    mWindowManager.lockNow(null);
16918                } else {
16919                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16920                    updateCurrentProfileIdsLocked();
16921                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16922                    mUserLru.remove(currentUserIdInt);
16923                    mUserLru.add(currentUserIdInt);
16924                }
16925
16926                final UserStartedState uss = mStartedUsers.get(userId);
16927
16928                // Make sure user is in the started state.  If it is currently
16929                // stopping, we need to knock that off.
16930                if (uss.mState == UserStartedState.STATE_STOPPING) {
16931                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16932                    // so we can just fairly silently bring the user back from
16933                    // the almost-dead.
16934                    uss.mState = UserStartedState.STATE_RUNNING;
16935                    updateStartedUserArrayLocked();
16936                    needStart = true;
16937                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16938                    // This means ACTION_SHUTDOWN has been sent, so we will
16939                    // need to treat this as a new boot of the user.
16940                    uss.mState = UserStartedState.STATE_BOOTING;
16941                    updateStartedUserArrayLocked();
16942                    needStart = true;
16943                }
16944
16945                if (uss.mState == UserStartedState.STATE_BOOTING) {
16946                    // Booting up a new user, need to tell system services about it.
16947                    // Note that this is on the same handler as scheduling of broadcasts,
16948                    // which is important because it needs to go first.
16949                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
16950                }
16951
16952                if (foreground) {
16953                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId));
16954                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16955                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16956                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16957                            oldUserId, userId, uss));
16958                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16959                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16960                }
16961
16962                if (needStart) {
16963                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16964                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16965                            | Intent.FLAG_RECEIVER_FOREGROUND);
16966                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16967                    broadcastIntentLocked(null, null, intent,
16968                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16969                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16970                }
16971
16972                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16973                    if (userId != UserHandle.USER_OWNER) {
16974                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16975                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16976                        broadcastIntentLocked(null, null, intent, null,
16977                                new IIntentReceiver.Stub() {
16978                                    public void performReceive(Intent intent, int resultCode,
16979                                            String data, Bundle extras, boolean ordered,
16980                                            boolean sticky, int sendingUser) {
16981                                        userInitialized(uss, userId);
16982                                    }
16983                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16984                                true, false, MY_PID, Process.SYSTEM_UID,
16985                                userId);
16986                        uss.initializing = true;
16987                    } else {
16988                        getUserManagerLocked().makeInitialized(userInfo.id);
16989                    }
16990                }
16991
16992                if (foreground) {
16993                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16994                    if (homeInFront) {
16995                        startHomeActivityLocked(userId);
16996                    } else {
16997                        mStackSupervisor.resumeTopActivitiesLocked();
16998                    }
16999                    EventLogTags.writeAmSwitchUser(userId);
17000                    getUserManagerLocked().userForeground(userId);
17001                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
17002                } else {
17003                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
17004                }
17005
17006                if (needStart) {
17007                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
17008                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17009                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17010                    broadcastIntentLocked(null, null, intent,
17011                            null, new IIntentReceiver.Stub() {
17012                                @Override
17013                                public void performReceive(Intent intent, int resultCode, String data,
17014                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
17015                                        throws RemoteException {
17016                                }
17017                            }, 0, null, null,
17018                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17019                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17020                }
17021            }
17022        } finally {
17023            Binder.restoreCallingIdentity(ident);
17024        }
17025
17026        return true;
17027    }
17028
17029    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
17030        long ident = Binder.clearCallingIdentity();
17031        try {
17032            Intent intent;
17033            if (oldUserId >= 0) {
17034                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
17035                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17036                        | Intent.FLAG_RECEIVER_FOREGROUND);
17037                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
17038                broadcastIntentLocked(null, null, intent,
17039                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17040                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
17041            }
17042            if (newUserId >= 0) {
17043                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
17044                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17045                        | Intent.FLAG_RECEIVER_FOREGROUND);
17046                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
17047                broadcastIntentLocked(null, null, intent,
17048                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17049                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
17050                intent = new Intent(Intent.ACTION_USER_SWITCHED);
17051                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17052                        | Intent.FLAG_RECEIVER_FOREGROUND);
17053                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
17054                broadcastIntentLocked(null, null, intent,
17055                        null, null, 0, null, null,
17056                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
17057                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17058            }
17059        } finally {
17060            Binder.restoreCallingIdentity(ident);
17061        }
17062    }
17063
17064    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
17065            final int newUserId) {
17066        final int N = mUserSwitchObservers.beginBroadcast();
17067        if (N > 0) {
17068            final IRemoteCallback callback = new IRemoteCallback.Stub() {
17069                int mCount = 0;
17070                @Override
17071                public void sendResult(Bundle data) throws RemoteException {
17072                    synchronized (ActivityManagerService.this) {
17073                        if (mCurUserSwitchCallback == this) {
17074                            mCount++;
17075                            if (mCount == N) {
17076                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17077                            }
17078                        }
17079                    }
17080                }
17081            };
17082            synchronized (this) {
17083                uss.switching = true;
17084                mCurUserSwitchCallback = callback;
17085            }
17086            for (int i=0; i<N; i++) {
17087                try {
17088                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17089                            newUserId, callback);
17090                } catch (RemoteException e) {
17091                }
17092            }
17093        } else {
17094            synchronized (this) {
17095                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17096            }
17097        }
17098        mUserSwitchObservers.finishBroadcast();
17099    }
17100
17101    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17102        synchronized (this) {
17103            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17104            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17105        }
17106    }
17107
17108    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17109        mCurUserSwitchCallback = null;
17110        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17111        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17112                oldUserId, newUserId, uss));
17113    }
17114
17115    void userInitialized(UserStartedState uss, int newUserId) {
17116        completeSwitchAndInitalize(uss, newUserId, true, false);
17117    }
17118
17119    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17120        completeSwitchAndInitalize(uss, newUserId, false, true);
17121    }
17122
17123    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17124            boolean clearInitializing, boolean clearSwitching) {
17125        boolean unfrozen = false;
17126        synchronized (this) {
17127            if (clearInitializing) {
17128                uss.initializing = false;
17129                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17130            }
17131            if (clearSwitching) {
17132                uss.switching = false;
17133            }
17134            if (!uss.switching && !uss.initializing) {
17135                mWindowManager.stopFreezingScreen();
17136                unfrozen = true;
17137            }
17138        }
17139        if (unfrozen) {
17140            final int N = mUserSwitchObservers.beginBroadcast();
17141            for (int i=0; i<N; i++) {
17142                try {
17143                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17144                } catch (RemoteException e) {
17145                }
17146            }
17147            mUserSwitchObservers.finishBroadcast();
17148        }
17149    }
17150
17151    void scheduleStartProfilesLocked() {
17152        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17153            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17154                    DateUtils.SECOND_IN_MILLIS);
17155        }
17156    }
17157
17158    void startProfilesLocked() {
17159        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17160        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17161                mCurrentUserId, false /* enabledOnly */);
17162        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17163        for (UserInfo user : profiles) {
17164            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17165                    && user.id != mCurrentUserId) {
17166                toStart.add(user);
17167            }
17168        }
17169        final int n = toStart.size();
17170        int i = 0;
17171        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17172            startUserInBackground(toStart.get(i).id);
17173        }
17174        if (i < n) {
17175            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17176        }
17177    }
17178
17179    void finishUserBoot(UserStartedState uss) {
17180        synchronized (this) {
17181            if (uss.mState == UserStartedState.STATE_BOOTING
17182                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17183                uss.mState = UserStartedState.STATE_RUNNING;
17184                final int userId = uss.mHandle.getIdentifier();
17185                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17186                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17187                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17188                broadcastIntentLocked(null, null, intent,
17189                        null, null, 0, null, null,
17190                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17191                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17192            }
17193        }
17194    }
17195
17196    void finishUserSwitch(UserStartedState uss) {
17197        synchronized (this) {
17198            finishUserBoot(uss);
17199
17200            startProfilesLocked();
17201
17202            int num = mUserLru.size();
17203            int i = 0;
17204            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17205                Integer oldUserId = mUserLru.get(i);
17206                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17207                if (oldUss == null) {
17208                    // Shouldn't happen, but be sane if it does.
17209                    mUserLru.remove(i);
17210                    num--;
17211                    continue;
17212                }
17213                if (oldUss.mState == UserStartedState.STATE_STOPPING
17214                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17215                    // This user is already stopping, doesn't count.
17216                    num--;
17217                    i++;
17218                    continue;
17219                }
17220                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17221                    // Owner and current can't be stopped, but count as running.
17222                    i++;
17223                    continue;
17224                }
17225                // This is a user to be stopped.
17226                stopUserLocked(oldUserId, null);
17227                num--;
17228                i++;
17229            }
17230        }
17231    }
17232
17233    @Override
17234    public int stopUser(final int userId, final IStopUserCallback callback) {
17235        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17236                != PackageManager.PERMISSION_GRANTED) {
17237            String msg = "Permission Denial: switchUser() from pid="
17238                    + Binder.getCallingPid()
17239                    + ", uid=" + Binder.getCallingUid()
17240                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17241            Slog.w(TAG, msg);
17242            throw new SecurityException(msg);
17243        }
17244        if (userId <= 0) {
17245            throw new IllegalArgumentException("Can't stop primary user " + userId);
17246        }
17247        synchronized (this) {
17248            return stopUserLocked(userId, callback);
17249        }
17250    }
17251
17252    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17253        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17254        if (mCurrentUserId == userId) {
17255            return ActivityManager.USER_OP_IS_CURRENT;
17256        }
17257
17258        final UserStartedState uss = mStartedUsers.get(userId);
17259        if (uss == null) {
17260            // User is not started, nothing to do...  but we do need to
17261            // callback if requested.
17262            if (callback != null) {
17263                mHandler.post(new Runnable() {
17264                    @Override
17265                    public void run() {
17266                        try {
17267                            callback.userStopped(userId);
17268                        } catch (RemoteException e) {
17269                        }
17270                    }
17271                });
17272            }
17273            return ActivityManager.USER_OP_SUCCESS;
17274        }
17275
17276        if (callback != null) {
17277            uss.mStopCallbacks.add(callback);
17278        }
17279
17280        if (uss.mState != UserStartedState.STATE_STOPPING
17281                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17282            uss.mState = UserStartedState.STATE_STOPPING;
17283            updateStartedUserArrayLocked();
17284
17285            long ident = Binder.clearCallingIdentity();
17286            try {
17287                // We are going to broadcast ACTION_USER_STOPPING and then
17288                // once that is done send a final ACTION_SHUTDOWN and then
17289                // stop the user.
17290                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17291                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17292                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17293                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17294                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17295                // This is the result receiver for the final shutdown broadcast.
17296                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17297                    @Override
17298                    public void performReceive(Intent intent, int resultCode, String data,
17299                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17300                        finishUserStop(uss);
17301                    }
17302                };
17303                // This is the result receiver for the initial stopping broadcast.
17304                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17305                    @Override
17306                    public void performReceive(Intent intent, int resultCode, String data,
17307                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17308                        // On to the next.
17309                        synchronized (ActivityManagerService.this) {
17310                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17311                                // Whoops, we are being started back up.  Abort, abort!
17312                                return;
17313                            }
17314                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17315                        }
17316                        mSystemServiceManager.stopUser(userId);
17317                        broadcastIntentLocked(null, null, shutdownIntent,
17318                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17319                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17320                    }
17321                };
17322                // Kick things off.
17323                broadcastIntentLocked(null, null, stoppingIntent,
17324                        null, stoppingReceiver, 0, null, null,
17325                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17326                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17327            } finally {
17328                Binder.restoreCallingIdentity(ident);
17329            }
17330        }
17331
17332        return ActivityManager.USER_OP_SUCCESS;
17333    }
17334
17335    void finishUserStop(UserStartedState uss) {
17336        final int userId = uss.mHandle.getIdentifier();
17337        boolean stopped;
17338        ArrayList<IStopUserCallback> callbacks;
17339        synchronized (this) {
17340            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17341            if (mStartedUsers.get(userId) != uss) {
17342                stopped = false;
17343            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17344                stopped = false;
17345            } else {
17346                stopped = true;
17347                // User can no longer run.
17348                mStartedUsers.remove(userId);
17349                mUserLru.remove(Integer.valueOf(userId));
17350                updateStartedUserArrayLocked();
17351
17352                // Clean up all state and processes associated with the user.
17353                // Kill all the processes for the user.
17354                forceStopUserLocked(userId, "finish user");
17355            }
17356        }
17357
17358        for (int i=0; i<callbacks.size(); i++) {
17359            try {
17360                if (stopped) callbacks.get(i).userStopped(userId);
17361                else callbacks.get(i).userStopAborted(userId);
17362            } catch (RemoteException e) {
17363            }
17364        }
17365
17366        if (stopped) {
17367            mSystemServiceManager.cleanupUser(userId);
17368            synchronized (this) {
17369                mStackSupervisor.removeUserLocked(userId);
17370            }
17371        }
17372    }
17373
17374    @Override
17375    public UserInfo getCurrentUser() {
17376        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17377                != PackageManager.PERMISSION_GRANTED) && (
17378                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17379                != PackageManager.PERMISSION_GRANTED)) {
17380            String msg = "Permission Denial: getCurrentUser() from pid="
17381                    + Binder.getCallingPid()
17382                    + ", uid=" + Binder.getCallingUid()
17383                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17384            Slog.w(TAG, msg);
17385            throw new SecurityException(msg);
17386        }
17387        synchronized (this) {
17388            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17389        }
17390    }
17391
17392    int getCurrentUserIdLocked() {
17393        return mCurrentUserId;
17394    }
17395
17396    @Override
17397    public boolean isUserRunning(int userId, boolean orStopped) {
17398        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17399                != PackageManager.PERMISSION_GRANTED) {
17400            String msg = "Permission Denial: isUserRunning() from pid="
17401                    + Binder.getCallingPid()
17402                    + ", uid=" + Binder.getCallingUid()
17403                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17404            Slog.w(TAG, msg);
17405            throw new SecurityException(msg);
17406        }
17407        synchronized (this) {
17408            return isUserRunningLocked(userId, orStopped);
17409        }
17410    }
17411
17412    boolean isUserRunningLocked(int userId, boolean orStopped) {
17413        UserStartedState state = mStartedUsers.get(userId);
17414        if (state == null) {
17415            return false;
17416        }
17417        if (orStopped) {
17418            return true;
17419        }
17420        return state.mState != UserStartedState.STATE_STOPPING
17421                && state.mState != UserStartedState.STATE_SHUTDOWN;
17422    }
17423
17424    @Override
17425    public int[] getRunningUserIds() {
17426        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17427                != PackageManager.PERMISSION_GRANTED) {
17428            String msg = "Permission Denial: isUserRunning() from pid="
17429                    + Binder.getCallingPid()
17430                    + ", uid=" + Binder.getCallingUid()
17431                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17432            Slog.w(TAG, msg);
17433            throw new SecurityException(msg);
17434        }
17435        synchronized (this) {
17436            return mStartedUserArray;
17437        }
17438    }
17439
17440    private void updateStartedUserArrayLocked() {
17441        int num = 0;
17442        for (int i=0; i<mStartedUsers.size();  i++) {
17443            UserStartedState uss = mStartedUsers.valueAt(i);
17444            // This list does not include stopping users.
17445            if (uss.mState != UserStartedState.STATE_STOPPING
17446                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17447                num++;
17448            }
17449        }
17450        mStartedUserArray = new int[num];
17451        num = 0;
17452        for (int i=0; i<mStartedUsers.size();  i++) {
17453            UserStartedState uss = mStartedUsers.valueAt(i);
17454            if (uss.mState != UserStartedState.STATE_STOPPING
17455                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17456                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17457                num++;
17458            }
17459        }
17460    }
17461
17462    @Override
17463    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17464        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17465                != PackageManager.PERMISSION_GRANTED) {
17466            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17467                    + Binder.getCallingPid()
17468                    + ", uid=" + Binder.getCallingUid()
17469                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17470            Slog.w(TAG, msg);
17471            throw new SecurityException(msg);
17472        }
17473
17474        mUserSwitchObservers.register(observer);
17475    }
17476
17477    @Override
17478    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17479        mUserSwitchObservers.unregister(observer);
17480    }
17481
17482    private boolean userExists(int userId) {
17483        if (userId == 0) {
17484            return true;
17485        }
17486        UserManagerService ums = getUserManagerLocked();
17487        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17488    }
17489
17490    int[] getUsersLocked() {
17491        UserManagerService ums = getUserManagerLocked();
17492        return ums != null ? ums.getUserIds() : new int[] { 0 };
17493    }
17494
17495    UserManagerService getUserManagerLocked() {
17496        if (mUserManager == null) {
17497            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17498            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17499        }
17500        return mUserManager;
17501    }
17502
17503    private int applyUserId(int uid, int userId) {
17504        return UserHandle.getUid(userId, uid);
17505    }
17506
17507    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17508        if (info == null) return null;
17509        ApplicationInfo newInfo = new ApplicationInfo(info);
17510        newInfo.uid = applyUserId(info.uid, userId);
17511        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17512                + info.packageName;
17513        return newInfo;
17514    }
17515
17516    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17517        if (aInfo == null
17518                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17519            return aInfo;
17520        }
17521
17522        ActivityInfo info = new ActivityInfo(aInfo);
17523        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17524        return info;
17525    }
17526
17527    private final class LocalService extends ActivityManagerInternal {
17528        @Override
17529        public void goingToSleep() {
17530            ActivityManagerService.this.goingToSleep();
17531        }
17532
17533        @Override
17534        public void wakingUp() {
17535            ActivityManagerService.this.wakingUp();
17536        }
17537    }
17538
17539    /**
17540     * An implementation of IAppTask, that allows an app to manage its own tasks via
17541     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17542     * only the process that calls getAppTasks() can call the AppTask methods.
17543     */
17544    class AppTaskImpl extends IAppTask.Stub {
17545        private int mTaskId;
17546        private int mCallingUid;
17547
17548        public AppTaskImpl(int taskId, int callingUid) {
17549            mTaskId = taskId;
17550            mCallingUid = callingUid;
17551        }
17552
17553        @Override
17554        public void finishAndRemoveTask() {
17555            // Ensure that we are called from the same process that created this AppTask
17556            if (mCallingUid != Binder.getCallingUid()) {
17557                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17558                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17559                return;
17560            }
17561
17562            synchronized (ActivityManagerService.this) {
17563                long origId = Binder.clearCallingIdentity();
17564                try {
17565                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17566                    if (tr != null) {
17567                        // Only kill the process if we are not a new document
17568                        int flags = tr.getBaseIntent().getFlags();
17569                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17570                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17571                        removeTaskByIdLocked(mTaskId,
17572                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17573                    }
17574                } finally {
17575                    Binder.restoreCallingIdentity(origId);
17576                }
17577            }
17578        }
17579
17580        @Override
17581        public ActivityManager.RecentTaskInfo getTaskInfo() {
17582            // Ensure that we are called from the same process that created this AppTask
17583            if (mCallingUid != Binder.getCallingUid()) {
17584                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17585                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17586                return null;
17587            }
17588
17589            synchronized (ActivityManagerService.this) {
17590                long origId = Binder.clearCallingIdentity();
17591                try {
17592                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17593                    if (tr != null) {
17594                        return createRecentTaskInfoFromTaskRecord(tr);
17595                    }
17596                } finally {
17597                    Binder.restoreCallingIdentity(origId);
17598                }
17599                return null;
17600            }
17601        }
17602    }
17603}
17604