ActivityManagerService.java revision 306af678a5f1938629e1182b46cc43f2da6e7774
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.content.DialogInterface.OnClickListener;
40import android.content.res.Resources;
41import android.graphics.BitmapFactory;
42import android.graphics.Rect;
43import android.os.BatteryStats;
44import android.os.PersistableBundle;
45import android.service.voice.IVoiceInteractionSession;
46import android.util.ArrayMap;
47
48import com.android.internal.R;
49import com.android.internal.annotations.GuardedBy;
50import com.android.internal.app.IAppOpsService;
51import com.android.internal.app.IVoiceInteractor;
52import com.android.internal.app.ProcessMap;
53import com.android.internal.app.ProcessStats;
54import com.android.internal.content.PackageMonitor;
55import com.android.internal.os.BackgroundThread;
56import com.android.internal.os.BatteryStatsImpl;
57import com.android.internal.os.ProcessCpuTracker;
58import com.android.internal.os.TransferPipe;
59import com.android.internal.os.Zygote;
60import com.android.internal.util.FastPrintWriter;
61import com.android.internal.util.FastXmlSerializer;
62import com.android.internal.util.MemInfoReader;
63import com.android.internal.util.Preconditions;
64import com.android.server.AppOpsService;
65import com.android.server.AttributeCache;
66import com.android.server.IntentResolver;
67import com.android.server.LocalServices;
68import com.android.server.ServiceThread;
69import com.android.server.SystemService;
70import com.android.server.SystemServiceManager;
71import com.android.server.Watchdog;
72import com.android.server.am.ActivityStack.ActivityState;
73import com.android.server.firewall.IntentFirewall;
74import com.android.server.pm.UserManagerService;
75import com.android.server.wm.AppTransition;
76import com.android.server.wm.WindowManagerService;
77import com.google.android.collect.Lists;
78import com.google.android.collect.Maps;
79
80import libcore.io.IoUtils;
81
82import org.xmlpull.v1.XmlPullParser;
83import org.xmlpull.v1.XmlPullParserException;
84import org.xmlpull.v1.XmlSerializer;
85
86import android.app.Activity;
87import android.app.ActivityManager;
88import android.app.ActivityManager.RunningTaskInfo;
89import android.app.ActivityManager.StackInfo;
90import android.app.ActivityManagerInternal;
91import android.app.ActivityManagerNative;
92import android.app.ActivityOptions;
93import android.app.ActivityThread;
94import android.app.AlertDialog;
95import android.app.AppGlobals;
96import android.app.ApplicationErrorReport;
97import android.app.Dialog;
98import android.app.IActivityController;
99import android.app.IApplicationThread;
100import android.app.IInstrumentationWatcher;
101import android.app.INotificationManager;
102import android.app.IProcessObserver;
103import android.app.IServiceConnection;
104import android.app.IStopUserCallback;
105import android.app.IUiAutomationConnection;
106import android.app.IUserSwitchObserver;
107import android.app.Instrumentation;
108import android.app.Notification;
109import android.app.NotificationManager;
110import android.app.PendingIntent;
111import android.app.backup.IBackupManager;
112import android.content.ActivityNotFoundException;
113import android.content.BroadcastReceiver;
114import android.content.ClipData;
115import android.content.ComponentCallbacks2;
116import android.content.ComponentName;
117import android.content.ContentProvider;
118import android.content.ContentResolver;
119import android.content.Context;
120import android.content.DialogInterface;
121import android.content.IContentProvider;
122import android.content.IIntentReceiver;
123import android.content.IIntentSender;
124import android.content.Intent;
125import android.content.IntentFilter;
126import android.content.IntentSender;
127import android.content.pm.ActivityInfo;
128import android.content.pm.ApplicationInfo;
129import android.content.pm.ConfigurationInfo;
130import android.content.pm.IPackageDataObserver;
131import android.content.pm.IPackageManager;
132import android.content.pm.InstrumentationInfo;
133import android.content.pm.PackageInfo;
134import android.content.pm.PackageManager;
135import android.content.pm.ParceledListSlice;
136import android.content.pm.UserInfo;
137import android.content.pm.PackageManager.NameNotFoundException;
138import android.content.pm.PathPermission;
139import android.content.pm.ProviderInfo;
140import android.content.pm.ResolveInfo;
141import android.content.pm.ServiceInfo;
142import android.content.res.CompatibilityInfo;
143import android.content.res.Configuration;
144import android.graphics.Bitmap;
145import android.net.Proxy;
146import android.net.ProxyInfo;
147import android.net.Uri;
148import android.os.Binder;
149import android.os.Build;
150import android.os.Bundle;
151import android.os.Debug;
152import android.os.DropBoxManager;
153import android.os.Environment;
154import android.os.FactoryTest;
155import android.os.FileObserver;
156import android.os.FileUtils;
157import android.os.Handler;
158import android.os.IBinder;
159import android.os.IPermissionController;
160import android.os.IRemoteCallback;
161import android.os.IUserManager;
162import android.os.Looper;
163import android.os.Message;
164import android.os.Parcel;
165import android.os.ParcelFileDescriptor;
166import android.os.Process;
167import android.os.RemoteCallbackList;
168import android.os.RemoteException;
169import android.os.SELinux;
170import android.os.ServiceManager;
171import android.os.StrictMode;
172import android.os.SystemClock;
173import android.os.SystemProperties;
174import android.os.UpdateLock;
175import android.os.UserHandle;
176import android.provider.Settings;
177import android.text.Spannable;
178import android.text.SpannableString;
179import android.text.format.DateUtils;
180import android.text.format.Time;
181import android.text.style.DynamicDrawableSpan;
182import android.text.style.ImageSpan;
183import android.util.AtomicFile;
184import android.util.EventLog;
185import android.util.Log;
186import android.util.Pair;
187import android.util.PrintWriterPrinter;
188import android.util.Slog;
189import android.util.SparseArray;
190import android.util.TimeUtils;
191import android.util.Xml;
192import android.view.Gravity;
193import android.view.LayoutInflater;
194import android.view.View;
195import android.view.WindowManager;
196import android.widget.TextView;
197
198import java.io.BufferedInputStream;
199import java.io.BufferedOutputStream;
200import java.io.DataInputStream;
201import java.io.DataOutputStream;
202import java.io.File;
203import java.io.FileDescriptor;
204import java.io.FileInputStream;
205import java.io.FileNotFoundException;
206import java.io.FileOutputStream;
207import java.io.IOException;
208import java.io.InputStreamReader;
209import java.io.PrintWriter;
210import java.io.StringWriter;
211import java.lang.ref.WeakReference;
212import java.util.ArrayList;
213import java.util.Arrays;
214import java.util.Collections;
215import java.util.Comparator;
216import java.util.HashMap;
217import java.util.HashSet;
218import java.util.Iterator;
219import java.util.List;
220import java.util.Locale;
221import java.util.Map;
222import java.util.Set;
223import java.util.concurrent.atomic.AtomicBoolean;
224import java.util.concurrent.atomic.AtomicLong;
225
226public final class ActivityManagerService extends ActivityManagerNative
227        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
228    private static final String USER_DATA_DIR = "/data/user/";
229    static final String TAG = "ActivityManager";
230    static final String TAG_MU = "ActivityManagerServiceMU";
231    static final boolean DEBUG = false;
232    static final boolean localLOGV = DEBUG;
233    static final boolean DEBUG_BACKUP = localLOGV || false;
234    static final boolean DEBUG_BROADCAST = localLOGV || false;
235    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
236    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
237    static final boolean DEBUG_CLEANUP = localLOGV || false;
238    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
239    static final boolean DEBUG_FOCUS = false;
240    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
241    static final boolean DEBUG_MU = localLOGV || false;
242    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
243    static final boolean DEBUG_LRU = localLOGV || false;
244    static final boolean DEBUG_PAUSE = localLOGV || false;
245    static final boolean DEBUG_POWER = localLOGV || false;
246    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
247    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
248    static final boolean DEBUG_PROCESSES = localLOGV || false;
249    static final boolean DEBUG_PROVIDER = localLOGV || false;
250    static final boolean DEBUG_RESULTS = localLOGV || false;
251    static final boolean DEBUG_SERVICE = localLOGV || false;
252    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
253    static final boolean DEBUG_STACK = localLOGV || false;
254    static final boolean DEBUG_SWITCH = localLOGV || false;
255    static final boolean DEBUG_TASKS = localLOGV || false;
256    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
257    static final boolean DEBUG_TRANSITION = localLOGV || false;
258    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
259    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
260    static final boolean DEBUG_VISBILITY = localLOGV || false;
261    static final boolean DEBUG_PSS = localLOGV || false;
262    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
263    static final boolean VALIDATE_TOKENS = false;
264    static final boolean SHOW_ACTIVITY_START_TIME = true;
265
266    // Control over CPU and battery monitoring.
267    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
268    static final boolean MONITOR_CPU_USAGE = true;
269    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
270    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
271    static final boolean MONITOR_THREAD_CPU_USAGE = false;
272
273    // The flags that are set for all calls we make to the package manager.
274    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
275
276    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
277
278    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
279
280    // Maximum number of recent tasks that we can remember.
281    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 200;
282
283    // Amount of time after a call to stopAppSwitches() during which we will
284    // prevent further untrusted switches from happening.
285    static final long APP_SWITCH_DELAY_TIME = 5*1000;
286
287    // How long we wait for a launched process to attach to the activity manager
288    // before we decide it's never going to come up for real.
289    static final int PROC_START_TIMEOUT = 10*1000;
290
291    // How long we wait for a launched process to attach to the activity manager
292    // before we decide it's never going to come up for real, when the process was
293    // started with a wrapper for instrumentation (such as Valgrind) because it
294    // could take much longer than usual.
295    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
296
297    // How long to wait after going idle before forcing apps to GC.
298    static final int GC_TIMEOUT = 5*1000;
299
300    // The minimum amount of time between successive GC requests for a process.
301    static final int GC_MIN_INTERVAL = 60*1000;
302
303    // The minimum amount of time between successive PSS requests for a process.
304    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
305
306    // The minimum amount of time between successive PSS requests for a process
307    // when the request is due to the memory state being lowered.
308    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
309
310    // The rate at which we check for apps using excessive power -- 15 mins.
311    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
312
313    // The minimum sample duration we will allow before deciding we have
314    // enough data on wake locks to start killing things.
315    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
316
317    // The minimum sample duration we will allow before deciding we have
318    // enough data on CPU usage to start killing things.
319    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
320
321    // How long we allow a receiver to run before giving up on it.
322    static final int BROADCAST_FG_TIMEOUT = 10*1000;
323    static final int BROADCAST_BG_TIMEOUT = 60*1000;
324
325    // How long we wait until we timeout on key dispatching.
326    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
327
328    // How long we wait until we timeout on key dispatching during instrumentation.
329    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
330
331    // Amount of time we wait for observers to handle a user switch before
332    // giving up on them and unfreezing the screen.
333    static final int USER_SWITCH_TIMEOUT = 2*1000;
334
335    // Maximum number of users we allow to be running at a time.
336    static final int MAX_RUNNING_USERS = 3;
337
338    // How long to wait in getAssistContextExtras for the activity and foreground services
339    // to respond with the result.
340    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
341
342    // Maximum number of persisted Uri grants a package is allowed
343    static final int MAX_PERSISTED_URI_GRANTS = 128;
344
345    static final int MY_PID = Process.myPid();
346
347    static final String[] EMPTY_STRING_ARRAY = new String[0];
348
349    // How many bytes to write into the dropbox log before truncating
350    static final int DROPBOX_MAX_SIZE = 256 * 1024;
351
352    /** All system services */
353    SystemServiceManager mSystemServiceManager;
354
355    /** Run all ActivityStacks through this */
356    ActivityStackSupervisor mStackSupervisor;
357
358    public IntentFirewall mIntentFirewall;
359
360    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
361    // default actuion automatically.  Important for devices without direct input
362    // devices.
363    private boolean mShowDialogs = true;
364
365    /**
366     * Description of a request to start a new activity, which has been held
367     * due to app switches being disabled.
368     */
369    static class PendingActivityLaunch {
370        final ActivityRecord r;
371        final ActivityRecord sourceRecord;
372        final int startFlags;
373        final ActivityStack stack;
374
375        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
376                int _startFlags, ActivityStack _stack) {
377            r = _r;
378            sourceRecord = _sourceRecord;
379            startFlags = _startFlags;
380            stack = _stack;
381        }
382    }
383
384    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
385            = new ArrayList<PendingActivityLaunch>();
386
387    BroadcastQueue mFgBroadcastQueue;
388    BroadcastQueue mBgBroadcastQueue;
389    // Convenient for easy iteration over the queues. Foreground is first
390    // so that dispatch of foreground broadcasts gets precedence.
391    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
392
393    BroadcastQueue broadcastQueueForIntent(Intent intent) {
394        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
395        if (DEBUG_BACKGROUND_BROADCAST) {
396            Slog.i(TAG, "Broadcast intent " + intent + " on "
397                    + (isFg ? "foreground" : "background")
398                    + " queue");
399        }
400        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
401    }
402
403    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
404        for (BroadcastQueue queue : mBroadcastQueues) {
405            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
406            if (r != null) {
407                return r;
408            }
409        }
410        return null;
411    }
412
413    /**
414     * Activity we have told the window manager to have key focus.
415     */
416    ActivityRecord mFocusedActivity = null;
417
418    /**
419     * List of intents that were used to start the most recent tasks.
420     */
421    ArrayList<TaskRecord> mRecentTasks;
422
423    public class PendingAssistExtras extends Binder implements Runnable {
424        public final ActivityRecord activity;
425        public boolean haveResult = false;
426        public Bundle result = null;
427        public PendingAssistExtras(ActivityRecord _activity) {
428            activity = _activity;
429        }
430        @Override
431        public void run() {
432            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
433            synchronized (this) {
434                haveResult = true;
435                notifyAll();
436            }
437        }
438    }
439
440    final ArrayList<PendingAssistExtras> mPendingAssistExtras
441            = new ArrayList<PendingAssistExtras>();
442
443    /**
444     * Process management.
445     */
446    final ProcessList mProcessList = new ProcessList();
447
448    /**
449     * All of the applications we currently have running organized by name.
450     * The keys are strings of the application package name (as
451     * returned by the package manager), and the keys are ApplicationRecord
452     * objects.
453     */
454    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
455
456    /**
457     * Tracking long-term execution of processes to look for abuse and other
458     * bad app behavior.
459     */
460    final ProcessStatsService mProcessStats;
461
462    /**
463     * The currently running isolated processes.
464     */
465    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
466
467    /**
468     * Counter for assigning isolated process uids, to avoid frequently reusing the
469     * same ones.
470     */
471    int mNextIsolatedProcessUid = 0;
472
473    /**
474     * The currently running heavy-weight process, if any.
475     */
476    ProcessRecord mHeavyWeightProcess = null;
477
478    /**
479     * The last time that various processes have crashed.
480     */
481    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
482
483    /**
484     * Information about a process that is currently marked as bad.
485     */
486    static final class BadProcessInfo {
487        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
488            this.time = time;
489            this.shortMsg = shortMsg;
490            this.longMsg = longMsg;
491            this.stack = stack;
492        }
493
494        final long time;
495        final String shortMsg;
496        final String longMsg;
497        final String stack;
498    }
499
500    /**
501     * Set of applications that we consider to be bad, and will reject
502     * incoming broadcasts from (which the user has no control over).
503     * Processes are added to this set when they have crashed twice within
504     * a minimum amount of time; they are removed from it when they are
505     * later restarted (hopefully due to some user action).  The value is the
506     * time it was added to the list.
507     */
508    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
509
510    /**
511     * All of the processes we currently have running organized by pid.
512     * The keys are the pid running the application.
513     *
514     * <p>NOTE: This object is protected by its own lock, NOT the global
515     * activity manager lock!
516     */
517    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
518
519    /**
520     * All of the processes that have been forced to be foreground.  The key
521     * is the pid of the caller who requested it (we hold a death
522     * link on it).
523     */
524    abstract class ForegroundToken implements IBinder.DeathRecipient {
525        int pid;
526        IBinder token;
527    }
528    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
529
530    /**
531     * List of records for processes that someone had tried to start before the
532     * system was ready.  We don't start them at that point, but ensure they
533     * are started by the time booting is complete.
534     */
535    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
536
537    /**
538     * List of persistent applications that are in the process
539     * of being started.
540     */
541    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
542
543    /**
544     * Processes that are being forcibly torn down.
545     */
546    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
547
548    /**
549     * List of running applications, sorted by recent usage.
550     * The first entry in the list is the least recently used.
551     */
552    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
553
554    /**
555     * Where in mLruProcesses that the processes hosting activities start.
556     */
557    int mLruProcessActivityStart = 0;
558
559    /**
560     * Where in mLruProcesses that the processes hosting services start.
561     * This is after (lower index) than mLruProcessesActivityStart.
562     */
563    int mLruProcessServiceStart = 0;
564
565    /**
566     * List of processes that should gc as soon as things are idle.
567     */
568    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
569
570    /**
571     * Processes we want to collect PSS data from.
572     */
573    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
574
575    /**
576     * Last time we requested PSS data of all processes.
577     */
578    long mLastFullPssTime = SystemClock.uptimeMillis();
579
580    /**
581     * If set, the next time we collect PSS data we should do a full collection
582     * with data from native processes and the kernel.
583     */
584    boolean mFullPssPending = false;
585
586    /**
587     * This is the process holding what we currently consider to be
588     * the "home" activity.
589     */
590    ProcessRecord mHomeProcess;
591
592    /**
593     * This is the process holding the activity the user last visited that
594     * is in a different process from the one they are currently in.
595     */
596    ProcessRecord mPreviousProcess;
597
598    /**
599     * The time at which the previous process was last visible.
600     */
601    long mPreviousProcessVisibleTime;
602
603    /**
604     * Which uses have been started, so are allowed to run code.
605     */
606    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
607
608    /**
609     * LRU list of history of current users.  Most recently current is at the end.
610     */
611    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
612
613    /**
614     * Constant array of the users that are currently started.
615     */
616    int[] mStartedUserArray = new int[] { 0 };
617
618    /**
619     * Registered observers of the user switching mechanics.
620     */
621    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
622            = new RemoteCallbackList<IUserSwitchObserver>();
623
624    /**
625     * Currently active user switch.
626     */
627    Object mCurUserSwitchCallback;
628
629    /**
630     * Packages that the user has asked to have run in screen size
631     * compatibility mode instead of filling the screen.
632     */
633    final CompatModePackages mCompatModePackages;
634
635    /**
636     * Set of IntentSenderRecord objects that are currently active.
637     */
638    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
639            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
640
641    /**
642     * Fingerprints (hashCode()) of stack traces that we've
643     * already logged DropBox entries for.  Guarded by itself.  If
644     * something (rogue user app) forces this over
645     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
646     */
647    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
648    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
649
650    /**
651     * Strict Mode background batched logging state.
652     *
653     * The string buffer is guarded by itself, and its lock is also
654     * used to determine if another batched write is already
655     * in-flight.
656     */
657    private final StringBuilder mStrictModeBuffer = new StringBuilder();
658
659    /**
660     * Keeps track of all IIntentReceivers that have been registered for
661     * broadcasts.  Hash keys are the receiver IBinder, hash value is
662     * a ReceiverList.
663     */
664    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
665            new HashMap<IBinder, ReceiverList>();
666
667    /**
668     * Resolver for broadcast intents to registered receivers.
669     * Holds BroadcastFilter (subclass of IntentFilter).
670     */
671    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
672            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
673        @Override
674        protected boolean allowFilterResult(
675                BroadcastFilter filter, List<BroadcastFilter> dest) {
676            IBinder target = filter.receiverList.receiver.asBinder();
677            for (int i=dest.size()-1; i>=0; i--) {
678                if (dest.get(i).receiverList.receiver.asBinder() == target) {
679                    return false;
680                }
681            }
682            return true;
683        }
684
685        @Override
686        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
687            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
688                    || userId == filter.owningUserId) {
689                return super.newResult(filter, match, userId);
690            }
691            return null;
692        }
693
694        @Override
695        protected BroadcastFilter[] newArray(int size) {
696            return new BroadcastFilter[size];
697        }
698
699        @Override
700        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
701            return packageName.equals(filter.packageName);
702        }
703    };
704
705    /**
706     * State of all active sticky broadcasts per user.  Keys are the action of the
707     * sticky Intent, values are an ArrayList of all broadcasted intents with
708     * that action (which should usually be one).  The SparseArray is keyed
709     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
710     * for stickies that are sent to all users.
711     */
712    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
713            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
714
715    final ActiveServices mServices;
716
717    /**
718     * Backup/restore process management
719     */
720    String mBackupAppName = null;
721    BackupRecord mBackupTarget = null;
722
723    final ProviderMap mProviderMap;
724
725    /**
726     * List of content providers who have clients waiting for them.  The
727     * application is currently being launched and the provider will be
728     * removed from this list once it is published.
729     */
730    final ArrayList<ContentProviderRecord> mLaunchingProviders
731            = new ArrayList<ContentProviderRecord>();
732
733    /**
734     * File storing persisted {@link #mGrantedUriPermissions}.
735     */
736    private final AtomicFile mGrantFile;
737
738    /** XML constants used in {@link #mGrantFile} */
739    private static final String TAG_URI_GRANTS = "uri-grants";
740    private static final String TAG_URI_GRANT = "uri-grant";
741    private static final String ATTR_USER_HANDLE = "userHandle";
742    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
743    private static final String ATTR_TARGET_USER_ID = "targetUserId";
744    private static final String ATTR_SOURCE_PKG = "sourcePkg";
745    private static final String ATTR_TARGET_PKG = "targetPkg";
746    private static final String ATTR_URI = "uri";
747    private static final String ATTR_MODE_FLAGS = "modeFlags";
748    private static final String ATTR_CREATED_TIME = "createdTime";
749    private static final String ATTR_PREFIX = "prefix";
750
751    /**
752     * Global set of specific {@link Uri} permissions that have been granted.
753     * This optimized lookup structure maps from {@link UriPermission#targetUid}
754     * to {@link UriPermission#uri} to {@link UriPermission}.
755     */
756    @GuardedBy("this")
757    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
758            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
759
760    public static class GrantUri {
761        public final int sourceUserId;
762        public final Uri uri;
763        public boolean prefix;
764
765        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
766            this.sourceUserId = sourceUserId;
767            this.uri = uri;
768            this.prefix = prefix;
769        }
770
771        @Override
772        public int hashCode() {
773            return toString().hashCode();
774        }
775
776        @Override
777        public boolean equals(Object o) {
778            if (o instanceof GrantUri) {
779                GrantUri other = (GrantUri) o;
780                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
781                        && prefix == other.prefix;
782            }
783            return false;
784        }
785
786        @Override
787        public String toString() {
788            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
789            if (prefix) result += " [prefix]";
790            return result;
791        }
792
793        public String toSafeString() {
794            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
795            if (prefix) result += " [prefix]";
796            return result;
797        }
798
799        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
800            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
801                    ContentProvider.getUriWithoutUserId(uri), false);
802        }
803    }
804
805    CoreSettingsObserver mCoreSettingsObserver;
806
807    /**
808     * Thread-local storage used to carry caller permissions over through
809     * indirect content-provider access.
810     */
811    private class Identity {
812        public int pid;
813        public int uid;
814
815        Identity(int _pid, int _uid) {
816            pid = _pid;
817            uid = _uid;
818        }
819    }
820
821    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
822
823    /**
824     * All information we have collected about the runtime performance of
825     * any user id that can impact battery performance.
826     */
827    final BatteryStatsService mBatteryStatsService;
828
829    /**
830     * Information about component usage
831     */
832    final UsageStatsService mUsageStatsService;
833
834    /**
835     * Information about and control over application operations
836     */
837    final AppOpsService mAppOpsService;
838
839    /**
840     * Save recent tasks information across reboots.
841     */
842    final TaskPersister mTaskPersister;
843
844    /**
845     * Current configuration information.  HistoryRecord objects are given
846     * a reference to this object to indicate which configuration they are
847     * currently running in, so this object must be kept immutable.
848     */
849    Configuration mConfiguration = new Configuration();
850
851    /**
852     * Current sequencing integer of the configuration, for skipping old
853     * configurations.
854     */
855    int mConfigurationSeq = 0;
856
857    /**
858     * Hardware-reported OpenGLES version.
859     */
860    final int GL_ES_VERSION;
861
862    /**
863     * List of initialization arguments to pass to all processes when binding applications to them.
864     * For example, references to the commonly used services.
865     */
866    HashMap<String, IBinder> mAppBindArgs;
867
868    /**
869     * Temporary to avoid allocations.  Protected by main lock.
870     */
871    final StringBuilder mStringBuilder = new StringBuilder(256);
872
873    /**
874     * Used to control how we initialize the service.
875     */
876    ComponentName mTopComponent;
877    String mTopAction = Intent.ACTION_MAIN;
878    String mTopData;
879    boolean mProcessesReady = false;
880    boolean mSystemReady = false;
881    boolean mBooting = false;
882    boolean mWaitingUpdate = false;
883    boolean mDidUpdate = false;
884    boolean mOnBattery = false;
885    boolean mLaunchWarningShown = false;
886
887    Context mContext;
888
889    int mFactoryTest;
890
891    boolean mCheckedForSetup;
892
893    /**
894     * The time at which we will allow normal application switches again,
895     * after a call to {@link #stopAppSwitches()}.
896     */
897    long mAppSwitchesAllowedTime;
898
899    /**
900     * This is set to true after the first switch after mAppSwitchesAllowedTime
901     * is set; any switches after that will clear the time.
902     */
903    boolean mDidAppSwitch;
904
905    /**
906     * Last time (in realtime) at which we checked for power usage.
907     */
908    long mLastPowerCheckRealtime;
909
910    /**
911     * Last time (in uptime) at which we checked for power usage.
912     */
913    long mLastPowerCheckUptime;
914
915    /**
916     * Set while we are wanting to sleep, to prevent any
917     * activities from being started/resumed.
918     */
919    private boolean mSleeping = false;
920
921    /**
922     * Set while we are running a voice interaction.  This overrides
923     * sleeping while it is active.
924     */
925    private boolean mRunningVoice = false;
926
927    /**
928     * State of external calls telling us if the device is asleep.
929     */
930    private boolean mWentToSleep = false;
931
932    /**
933     * State of external call telling us if the lock screen is shown.
934     */
935    private boolean mLockScreenShown = false;
936
937    /**
938     * Set if we are shutting down the system, similar to sleeping.
939     */
940    boolean mShuttingDown = false;
941
942    /**
943     * Current sequence id for oom_adj computation traversal.
944     */
945    int mAdjSeq = 0;
946
947    /**
948     * Current sequence id for process LRU updating.
949     */
950    int mLruSeq = 0;
951
952    /**
953     * Keep track of the non-cached/empty process we last found, to help
954     * determine how to distribute cached/empty processes next time.
955     */
956    int mNumNonCachedProcs = 0;
957
958    /**
959     * Keep track of the number of cached hidden procs, to balance oom adj
960     * distribution between those and empty procs.
961     */
962    int mNumCachedHiddenProcs = 0;
963
964    /**
965     * Keep track of the number of service processes we last found, to
966     * determine on the next iteration which should be B services.
967     */
968    int mNumServiceProcs = 0;
969    int mNewNumAServiceProcs = 0;
970    int mNewNumServiceProcs = 0;
971
972    /**
973     * Allow the current computed overall memory level of the system to go down?
974     * This is set to false when we are killing processes for reasons other than
975     * memory management, so that the now smaller process list will not be taken as
976     * an indication that memory is tighter.
977     */
978    boolean mAllowLowerMemLevel = false;
979
980    /**
981     * The last computed memory level, for holding when we are in a state that
982     * processes are going away for other reasons.
983     */
984    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
985
986    /**
987     * The last total number of process we have, to determine if changes actually look
988     * like a shrinking number of process due to lower RAM.
989     */
990    int mLastNumProcesses;
991
992    /**
993     * The uptime of the last time we performed idle maintenance.
994     */
995    long mLastIdleTime = SystemClock.uptimeMillis();
996
997    /**
998     * Total time spent with RAM that has been added in the past since the last idle time.
999     */
1000    long mLowRamTimeSinceLastIdle = 0;
1001
1002    /**
1003     * If RAM is currently low, when that horrible situation started.
1004     */
1005    long mLowRamStartTime = 0;
1006
1007    /**
1008     * For reporting to battery stats the current top application.
1009     */
1010    private String mCurResumedPackage = null;
1011    private int mCurResumedUid = -1;
1012
1013    /**
1014     * For reporting to battery stats the apps currently running foreground
1015     * service.  The ProcessMap is package/uid tuples; each of these contain
1016     * an array of the currently foreground processes.
1017     */
1018    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1019            = new ProcessMap<ArrayList<ProcessRecord>>();
1020
1021    /**
1022     * This is set if we had to do a delayed dexopt of an app before launching
1023     * it, to increase the ANR timeouts in that case.
1024     */
1025    boolean mDidDexOpt;
1026
1027    /**
1028     * Set if the systemServer made a call to enterSafeMode.
1029     */
1030    boolean mSafeMode;
1031
1032    String mDebugApp = null;
1033    boolean mWaitForDebugger = false;
1034    boolean mDebugTransient = false;
1035    String mOrigDebugApp = null;
1036    boolean mOrigWaitForDebugger = false;
1037    boolean mAlwaysFinishActivities = false;
1038    IActivityController mController = null;
1039    String mProfileApp = null;
1040    ProcessRecord mProfileProc = null;
1041    String mProfileFile;
1042    ParcelFileDescriptor mProfileFd;
1043    int mProfileType = 0;
1044    boolean mAutoStopProfiler = false;
1045    String mOpenGlTraceApp = null;
1046
1047    static class ProcessChangeItem {
1048        static final int CHANGE_ACTIVITIES = 1<<0;
1049        static final int CHANGE_PROCESS_STATE = 1<<1;
1050        int changes;
1051        int uid;
1052        int pid;
1053        int processState;
1054        boolean foregroundActivities;
1055    }
1056
1057    final RemoteCallbackList<IProcessObserver> mProcessObservers
1058            = new RemoteCallbackList<IProcessObserver>();
1059    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1060
1061    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1062            = new ArrayList<ProcessChangeItem>();
1063    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1064            = new ArrayList<ProcessChangeItem>();
1065
1066    /**
1067     * Runtime CPU use collection thread.  This object's lock is used to
1068     * protect all related state.
1069     */
1070    final Thread mProcessCpuThread;
1071
1072    /**
1073     * Used to collect process stats when showing not responding dialog.
1074     * Protected by mProcessCpuThread.
1075     */
1076    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1077            MONITOR_THREAD_CPU_USAGE);
1078    final AtomicLong mLastCpuTime = new AtomicLong(0);
1079    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1080
1081    long mLastWriteTime = 0;
1082
1083    /**
1084     * Used to retain an update lock when the foreground activity is in
1085     * immersive mode.
1086     */
1087    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1088
1089    /**
1090     * Set to true after the system has finished booting.
1091     */
1092    boolean mBooted = false;
1093
1094    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1095    int mProcessLimitOverride = -1;
1096
1097    WindowManagerService mWindowManager;
1098
1099    final ActivityThread mSystemThread;
1100
1101    int mCurrentUserId = 0;
1102    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1103    private UserManagerService mUserManager;
1104
1105    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1106        final ProcessRecord mApp;
1107        final int mPid;
1108        final IApplicationThread mAppThread;
1109
1110        AppDeathRecipient(ProcessRecord app, int pid,
1111                IApplicationThread thread) {
1112            if (localLOGV) Slog.v(
1113                TAG, "New death recipient " + this
1114                + " for thread " + thread.asBinder());
1115            mApp = app;
1116            mPid = pid;
1117            mAppThread = thread;
1118        }
1119
1120        @Override
1121        public void binderDied() {
1122            if (localLOGV) Slog.v(
1123                TAG, "Death received in " + this
1124                + " for thread " + mAppThread.asBinder());
1125            synchronized(ActivityManagerService.this) {
1126                appDiedLocked(mApp, mPid, mAppThread);
1127            }
1128        }
1129    }
1130
1131    static final int SHOW_ERROR_MSG = 1;
1132    static final int SHOW_NOT_RESPONDING_MSG = 2;
1133    static final int SHOW_FACTORY_ERROR_MSG = 3;
1134    static final int UPDATE_CONFIGURATION_MSG = 4;
1135    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1136    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1137    static final int SERVICE_TIMEOUT_MSG = 12;
1138    static final int UPDATE_TIME_ZONE = 13;
1139    static final int SHOW_UID_ERROR_MSG = 14;
1140    static final int IM_FEELING_LUCKY_MSG = 15;
1141    static final int PROC_START_TIMEOUT_MSG = 20;
1142    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1143    static final int KILL_APPLICATION_MSG = 22;
1144    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1145    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1146    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1147    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1148    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1149    static final int CLEAR_DNS_CACHE_MSG = 28;
1150    static final int UPDATE_HTTP_PROXY_MSG = 29;
1151    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1152    static final int DISPATCH_PROCESSES_CHANGED = 31;
1153    static final int DISPATCH_PROCESS_DIED = 32;
1154    static final int REPORT_MEM_USAGE_MSG = 33;
1155    static final int REPORT_USER_SWITCH_MSG = 34;
1156    static final int CONTINUE_USER_SWITCH_MSG = 35;
1157    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1158    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1159    static final int PERSIST_URI_GRANTS_MSG = 38;
1160    static final int REQUEST_ALL_PSS_MSG = 39;
1161    static final int START_PROFILES_MSG = 40;
1162    static final int UPDATE_TIME = 41;
1163    static final int SYSTEM_USER_START_MSG = 42;
1164    static final int SYSTEM_USER_CURRENT_MSG = 43;
1165
1166    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1167    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1168    static final int FIRST_COMPAT_MODE_MSG = 300;
1169    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1170
1171    AlertDialog mUidAlert;
1172    CompatModeDialog mCompatModeDialog;
1173    long mLastMemUsageReportTime = 0;
1174
1175    private LockToAppRequestDialog mLockToAppRequest;
1176
1177    /**
1178     * Flag whether the current user is a "monkey", i.e. whether
1179     * the UI is driven by a UI automation tool.
1180     */
1181    private boolean mUserIsMonkey;
1182
1183    final ServiceThread mHandlerThread;
1184    final MainHandler mHandler;
1185
1186    final class MainHandler extends Handler {
1187        public MainHandler(Looper looper) {
1188            super(looper, null, true);
1189        }
1190
1191        @Override
1192        public void handleMessage(Message msg) {
1193            switch (msg.what) {
1194            case SHOW_ERROR_MSG: {
1195                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1196                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1197                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1198                synchronized (ActivityManagerService.this) {
1199                    ProcessRecord proc = (ProcessRecord)data.get("app");
1200                    AppErrorResult res = (AppErrorResult) data.get("result");
1201                    if (proc != null && proc.crashDialog != null) {
1202                        Slog.e(TAG, "App already has crash dialog: " + proc);
1203                        if (res != null) {
1204                            res.set(0);
1205                        }
1206                        return;
1207                    }
1208                    if (!showBackground && UserHandle.getAppId(proc.uid)
1209                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1210                            && proc.pid != MY_PID) {
1211                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1212                        if (res != null) {
1213                            res.set(0);
1214                        }
1215                        return;
1216                    }
1217                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1218                        Dialog d = new AppErrorDialog(mContext,
1219                                ActivityManagerService.this, res, proc);
1220                        d.show();
1221                        proc.crashDialog = d;
1222                    } else {
1223                        // The device is asleep, so just pretend that the user
1224                        // saw a crash dialog and hit "force quit".
1225                        if (res != null) {
1226                            res.set(0);
1227                        }
1228                    }
1229                }
1230
1231                ensureBootCompleted();
1232            } break;
1233            case SHOW_NOT_RESPONDING_MSG: {
1234                synchronized (ActivityManagerService.this) {
1235                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1236                    ProcessRecord proc = (ProcessRecord)data.get("app");
1237                    if (proc != null && proc.anrDialog != null) {
1238                        Slog.e(TAG, "App already has anr dialog: " + proc);
1239                        return;
1240                    }
1241
1242                    Intent intent = new Intent("android.intent.action.ANR");
1243                    if (!mProcessesReady) {
1244                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1245                                | Intent.FLAG_RECEIVER_FOREGROUND);
1246                    }
1247                    broadcastIntentLocked(null, null, intent,
1248                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1249                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1250
1251                    if (mShowDialogs) {
1252                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1253                                mContext, proc, (ActivityRecord)data.get("activity"),
1254                                msg.arg1 != 0);
1255                        d.show();
1256                        proc.anrDialog = d;
1257                    } else {
1258                        // Just kill the app if there is no dialog to be shown.
1259                        killAppAtUsersRequest(proc, null);
1260                    }
1261                }
1262
1263                ensureBootCompleted();
1264            } break;
1265            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1266                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1267                synchronized (ActivityManagerService.this) {
1268                    ProcessRecord proc = (ProcessRecord) data.get("app");
1269                    if (proc == null) {
1270                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1271                        break;
1272                    }
1273                    if (proc.crashDialog != null) {
1274                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1275                        return;
1276                    }
1277                    AppErrorResult res = (AppErrorResult) data.get("result");
1278                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1279                        Dialog d = new StrictModeViolationDialog(mContext,
1280                                ActivityManagerService.this, res, proc);
1281                        d.show();
1282                        proc.crashDialog = d;
1283                    } else {
1284                        // The device is asleep, so just pretend that the user
1285                        // saw a crash dialog and hit "force quit".
1286                        res.set(0);
1287                    }
1288                }
1289                ensureBootCompleted();
1290            } break;
1291            case SHOW_FACTORY_ERROR_MSG: {
1292                Dialog d = new FactoryErrorDialog(
1293                    mContext, msg.getData().getCharSequence("msg"));
1294                d.show();
1295                ensureBootCompleted();
1296            } break;
1297            case UPDATE_CONFIGURATION_MSG: {
1298                final ContentResolver resolver = mContext.getContentResolver();
1299                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1300            } break;
1301            case GC_BACKGROUND_PROCESSES_MSG: {
1302                synchronized (ActivityManagerService.this) {
1303                    performAppGcsIfAppropriateLocked();
1304                }
1305            } break;
1306            case WAIT_FOR_DEBUGGER_MSG: {
1307                synchronized (ActivityManagerService.this) {
1308                    ProcessRecord app = (ProcessRecord)msg.obj;
1309                    if (msg.arg1 != 0) {
1310                        if (!app.waitedForDebugger) {
1311                            Dialog d = new AppWaitingForDebuggerDialog(
1312                                    ActivityManagerService.this,
1313                                    mContext, app);
1314                            app.waitDialog = d;
1315                            app.waitedForDebugger = true;
1316                            d.show();
1317                        }
1318                    } else {
1319                        if (app.waitDialog != null) {
1320                            app.waitDialog.dismiss();
1321                            app.waitDialog = null;
1322                        }
1323                    }
1324                }
1325            } break;
1326            case SERVICE_TIMEOUT_MSG: {
1327                if (mDidDexOpt) {
1328                    mDidDexOpt = false;
1329                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1330                    nmsg.obj = msg.obj;
1331                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1332                    return;
1333                }
1334                mServices.serviceTimeout((ProcessRecord)msg.obj);
1335            } break;
1336            case UPDATE_TIME_ZONE: {
1337                synchronized (ActivityManagerService.this) {
1338                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1339                        ProcessRecord r = mLruProcesses.get(i);
1340                        if (r.thread != null) {
1341                            try {
1342                                r.thread.updateTimeZone();
1343                            } catch (RemoteException ex) {
1344                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1345                            }
1346                        }
1347                    }
1348                }
1349            } break;
1350            case CLEAR_DNS_CACHE_MSG: {
1351                synchronized (ActivityManagerService.this) {
1352                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1353                        ProcessRecord r = mLruProcesses.get(i);
1354                        if (r.thread != null) {
1355                            try {
1356                                r.thread.clearDnsCache();
1357                            } catch (RemoteException ex) {
1358                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1359                            }
1360                        }
1361                    }
1362                }
1363            } break;
1364            case UPDATE_HTTP_PROXY_MSG: {
1365                ProxyInfo proxy = (ProxyInfo)msg.obj;
1366                String host = "";
1367                String port = "";
1368                String exclList = "";
1369                Uri pacFileUrl = Uri.EMPTY;
1370                if (proxy != null) {
1371                    host = proxy.getHost();
1372                    port = Integer.toString(proxy.getPort());
1373                    exclList = proxy.getExclusionListAsString();
1374                    pacFileUrl = proxy.getPacFileUrl();
1375                }
1376                synchronized (ActivityManagerService.this) {
1377                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1378                        ProcessRecord r = mLruProcesses.get(i);
1379                        if (r.thread != null) {
1380                            try {
1381                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1382                            } catch (RemoteException ex) {
1383                                Slog.w(TAG, "Failed to update http proxy for: " +
1384                                        r.info.processName);
1385                            }
1386                        }
1387                    }
1388                }
1389            } break;
1390            case SHOW_UID_ERROR_MSG: {
1391                String title = "System UIDs Inconsistent";
1392                String text = "UIDs on the system are inconsistent, you need to wipe your"
1393                        + " data partition or your device will be unstable.";
1394                Log.e(TAG, title + ": " + text);
1395                if (mShowDialogs) {
1396                    // XXX This is a temporary dialog, no need to localize.
1397                    AlertDialog d = new BaseErrorDialog(mContext);
1398                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1399                    d.setCancelable(false);
1400                    d.setTitle(title);
1401                    d.setMessage(text);
1402                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1403                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1404                    mUidAlert = d;
1405                    d.show();
1406                }
1407            } break;
1408            case IM_FEELING_LUCKY_MSG: {
1409                if (mUidAlert != null) {
1410                    mUidAlert.dismiss();
1411                    mUidAlert = null;
1412                }
1413            } break;
1414            case PROC_START_TIMEOUT_MSG: {
1415                if (mDidDexOpt) {
1416                    mDidDexOpt = false;
1417                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1418                    nmsg.obj = msg.obj;
1419                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1420                    return;
1421                }
1422                ProcessRecord app = (ProcessRecord)msg.obj;
1423                synchronized (ActivityManagerService.this) {
1424                    processStartTimedOutLocked(app);
1425                }
1426            } break;
1427            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1428                synchronized (ActivityManagerService.this) {
1429                    doPendingActivityLaunchesLocked(true);
1430                }
1431            } break;
1432            case KILL_APPLICATION_MSG: {
1433                synchronized (ActivityManagerService.this) {
1434                    int appid = msg.arg1;
1435                    boolean restart = (msg.arg2 == 1);
1436                    Bundle bundle = (Bundle)msg.obj;
1437                    String pkg = bundle.getString("pkg");
1438                    String reason = bundle.getString("reason");
1439                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1440                            false, UserHandle.USER_ALL, reason);
1441                }
1442            } break;
1443            case FINALIZE_PENDING_INTENT_MSG: {
1444                ((PendingIntentRecord)msg.obj).completeFinalize();
1445            } break;
1446            case POST_HEAVY_NOTIFICATION_MSG: {
1447                INotificationManager inm = NotificationManager.getService();
1448                if (inm == null) {
1449                    return;
1450                }
1451
1452                ActivityRecord root = (ActivityRecord)msg.obj;
1453                ProcessRecord process = root.app;
1454                if (process == null) {
1455                    return;
1456                }
1457
1458                try {
1459                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1460                    String text = mContext.getString(R.string.heavy_weight_notification,
1461                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1462                    Notification notification = new Notification();
1463                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1464                    notification.when = 0;
1465                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1466                    notification.tickerText = text;
1467                    notification.defaults = 0; // please be quiet
1468                    notification.sound = null;
1469                    notification.vibrate = null;
1470                    notification.setLatestEventInfo(context, text,
1471                            mContext.getText(R.string.heavy_weight_notification_detail),
1472                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1473                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1474                                    new UserHandle(root.userId)));
1475
1476                    try {
1477                        int[] outId = new int[1];
1478                        inm.enqueueNotificationWithTag("android", "android", null,
1479                                R.string.heavy_weight_notification,
1480                                notification, outId, root.userId);
1481                    } catch (RuntimeException e) {
1482                        Slog.w(ActivityManagerService.TAG,
1483                                "Error showing notification for heavy-weight app", e);
1484                    } catch (RemoteException e) {
1485                    }
1486                } catch (NameNotFoundException e) {
1487                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1488                }
1489            } break;
1490            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1491                INotificationManager inm = NotificationManager.getService();
1492                if (inm == null) {
1493                    return;
1494                }
1495                try {
1496                    inm.cancelNotificationWithTag("android", null,
1497                            R.string.heavy_weight_notification,  msg.arg1);
1498                } catch (RuntimeException e) {
1499                    Slog.w(ActivityManagerService.TAG,
1500                            "Error canceling notification for service", e);
1501                } catch (RemoteException e) {
1502                }
1503            } break;
1504            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1505                synchronized (ActivityManagerService.this) {
1506                    checkExcessivePowerUsageLocked(true);
1507                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1508                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1509                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1510                }
1511            } break;
1512            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1513                synchronized (ActivityManagerService.this) {
1514                    ActivityRecord ar = (ActivityRecord)msg.obj;
1515                    if (mCompatModeDialog != null) {
1516                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1517                                ar.info.applicationInfo.packageName)) {
1518                            return;
1519                        }
1520                        mCompatModeDialog.dismiss();
1521                        mCompatModeDialog = null;
1522                    }
1523                    if (ar != null && false) {
1524                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1525                                ar.packageName)) {
1526                            int mode = mCompatModePackages.computeCompatModeLocked(
1527                                    ar.info.applicationInfo);
1528                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1529                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1530                                mCompatModeDialog = new CompatModeDialog(
1531                                        ActivityManagerService.this, mContext,
1532                                        ar.info.applicationInfo);
1533                                mCompatModeDialog.show();
1534                            }
1535                        }
1536                    }
1537                }
1538                break;
1539            }
1540            case DISPATCH_PROCESSES_CHANGED: {
1541                dispatchProcessesChanged();
1542                break;
1543            }
1544            case DISPATCH_PROCESS_DIED: {
1545                final int pid = msg.arg1;
1546                final int uid = msg.arg2;
1547                dispatchProcessDied(pid, uid);
1548                break;
1549            }
1550            case REPORT_MEM_USAGE_MSG: {
1551                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1552                Thread thread = new Thread() {
1553                    @Override public void run() {
1554                        final SparseArray<ProcessMemInfo> infoMap
1555                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1556                        for (int i=0, N=memInfos.size(); i<N; i++) {
1557                            ProcessMemInfo mi = memInfos.get(i);
1558                            infoMap.put(mi.pid, mi);
1559                        }
1560                        updateCpuStatsNow();
1561                        synchronized (mProcessCpuThread) {
1562                            final int N = mProcessCpuTracker.countStats();
1563                            for (int i=0; i<N; i++) {
1564                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1565                                if (st.vsize > 0) {
1566                                    long pss = Debug.getPss(st.pid, null);
1567                                    if (pss > 0) {
1568                                        if (infoMap.indexOfKey(st.pid) < 0) {
1569                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1570                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1571                                            mi.pss = pss;
1572                                            memInfos.add(mi);
1573                                        }
1574                                    }
1575                                }
1576                            }
1577                        }
1578
1579                        long totalPss = 0;
1580                        for (int i=0, N=memInfos.size(); i<N; i++) {
1581                            ProcessMemInfo mi = memInfos.get(i);
1582                            if (mi.pss == 0) {
1583                                mi.pss = Debug.getPss(mi.pid, null);
1584                            }
1585                            totalPss += mi.pss;
1586                        }
1587                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1588                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1589                                if (lhs.oomAdj != rhs.oomAdj) {
1590                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1591                                }
1592                                if (lhs.pss != rhs.pss) {
1593                                    return lhs.pss < rhs.pss ? 1 : -1;
1594                                }
1595                                return 0;
1596                            }
1597                        });
1598
1599                        StringBuilder tag = new StringBuilder(128);
1600                        StringBuilder stack = new StringBuilder(128);
1601                        tag.append("Low on memory -- ");
1602                        appendMemBucket(tag, totalPss, "total", false);
1603                        appendMemBucket(stack, totalPss, "total", true);
1604
1605                        StringBuilder logBuilder = new StringBuilder(1024);
1606                        logBuilder.append("Low on memory:\n");
1607
1608                        boolean firstLine = true;
1609                        int lastOomAdj = Integer.MIN_VALUE;
1610                        for (int i=0, N=memInfos.size(); i<N; i++) {
1611                            ProcessMemInfo mi = memInfos.get(i);
1612
1613                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1614                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1615                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1616                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1617                                if (lastOomAdj != mi.oomAdj) {
1618                                    lastOomAdj = mi.oomAdj;
1619                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1620                                        tag.append(" / ");
1621                                    }
1622                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1623                                        if (firstLine) {
1624                                            stack.append(":");
1625                                            firstLine = false;
1626                                        }
1627                                        stack.append("\n\t at ");
1628                                    } else {
1629                                        stack.append("$");
1630                                    }
1631                                } else {
1632                                    tag.append(" ");
1633                                    stack.append("$");
1634                                }
1635                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1636                                    appendMemBucket(tag, mi.pss, mi.name, false);
1637                                }
1638                                appendMemBucket(stack, mi.pss, mi.name, true);
1639                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1640                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1641                                    stack.append("(");
1642                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1643                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1644                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1645                                            stack.append(":");
1646                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1647                                        }
1648                                    }
1649                                    stack.append(")");
1650                                }
1651                            }
1652
1653                            logBuilder.append("  ");
1654                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1655                            logBuilder.append(' ');
1656                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1657                            logBuilder.append(' ');
1658                            ProcessList.appendRamKb(logBuilder, mi.pss);
1659                            logBuilder.append(" kB: ");
1660                            logBuilder.append(mi.name);
1661                            logBuilder.append(" (");
1662                            logBuilder.append(mi.pid);
1663                            logBuilder.append(") ");
1664                            logBuilder.append(mi.adjType);
1665                            logBuilder.append('\n');
1666                            if (mi.adjReason != null) {
1667                                logBuilder.append("                      ");
1668                                logBuilder.append(mi.adjReason);
1669                                logBuilder.append('\n');
1670                            }
1671                        }
1672
1673                        logBuilder.append("           ");
1674                        ProcessList.appendRamKb(logBuilder, totalPss);
1675                        logBuilder.append(" kB: TOTAL\n");
1676
1677                        long[] infos = new long[Debug.MEMINFO_COUNT];
1678                        Debug.getMemInfo(infos);
1679                        logBuilder.append("  MemInfo: ");
1680                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1681                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1682                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1683                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1684                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1685                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1686                            logBuilder.append("  ZRAM: ");
1687                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1688                            logBuilder.append(" kB RAM, ");
1689                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1690                            logBuilder.append(" kB swap total, ");
1691                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1692                            logBuilder.append(" kB swap free\n");
1693                        }
1694                        Slog.i(TAG, logBuilder.toString());
1695
1696                        StringBuilder dropBuilder = new StringBuilder(1024);
1697                        /*
1698                        StringWriter oomSw = new StringWriter();
1699                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1700                        StringWriter catSw = new StringWriter();
1701                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1702                        String[] emptyArgs = new String[] { };
1703                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1704                        oomPw.flush();
1705                        String oomString = oomSw.toString();
1706                        */
1707                        dropBuilder.append(stack);
1708                        dropBuilder.append('\n');
1709                        dropBuilder.append('\n');
1710                        dropBuilder.append(logBuilder);
1711                        dropBuilder.append('\n');
1712                        /*
1713                        dropBuilder.append(oomString);
1714                        dropBuilder.append('\n');
1715                        */
1716                        StringWriter catSw = new StringWriter();
1717                        synchronized (ActivityManagerService.this) {
1718                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1719                            String[] emptyArgs = new String[] { };
1720                            catPw.println();
1721                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1722                            catPw.println();
1723                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1724                                    false, false, null);
1725                            catPw.println();
1726                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1727                            catPw.flush();
1728                        }
1729                        dropBuilder.append(catSw.toString());
1730                        addErrorToDropBox("lowmem", null, "system_server", null,
1731                                null, tag.toString(), dropBuilder.toString(), null, null);
1732                        //Slog.i(TAG, "Sent to dropbox:");
1733                        //Slog.i(TAG, dropBuilder.toString());
1734                        synchronized (ActivityManagerService.this) {
1735                            long now = SystemClock.uptimeMillis();
1736                            if (mLastMemUsageReportTime < now) {
1737                                mLastMemUsageReportTime = now;
1738                            }
1739                        }
1740                    }
1741                };
1742                thread.start();
1743                break;
1744            }
1745            case REPORT_USER_SWITCH_MSG: {
1746                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1747                break;
1748            }
1749            case CONTINUE_USER_SWITCH_MSG: {
1750                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1751                break;
1752            }
1753            case USER_SWITCH_TIMEOUT_MSG: {
1754                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1755                break;
1756            }
1757            case IMMERSIVE_MODE_LOCK_MSG: {
1758                final boolean nextState = (msg.arg1 != 0);
1759                if (mUpdateLock.isHeld() != nextState) {
1760                    if (DEBUG_IMMERSIVE) {
1761                        final ActivityRecord r = (ActivityRecord) msg.obj;
1762                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1763                    }
1764                    if (nextState) {
1765                        mUpdateLock.acquire();
1766                    } else {
1767                        mUpdateLock.release();
1768                    }
1769                }
1770                break;
1771            }
1772            case PERSIST_URI_GRANTS_MSG: {
1773                writeGrantedUriPermissions();
1774                break;
1775            }
1776            case REQUEST_ALL_PSS_MSG: {
1777                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1778                break;
1779            }
1780            case START_PROFILES_MSG: {
1781                synchronized (ActivityManagerService.this) {
1782                    startProfilesLocked();
1783                }
1784                break;
1785            }
1786            case UPDATE_TIME: {
1787                synchronized (ActivityManagerService.this) {
1788                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1789                        ProcessRecord r = mLruProcesses.get(i);
1790                        if (r.thread != null) {
1791                            try {
1792                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1793                            } catch (RemoteException ex) {
1794                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1795                            }
1796                        }
1797                    }
1798                }
1799                break;
1800            }
1801            case SYSTEM_USER_START_MSG: {
1802                mSystemServiceManager.startUser(msg.arg1);
1803                break;
1804            }
1805            case SYSTEM_USER_CURRENT_MSG: {
1806                mSystemServiceManager.switchUser(msg.arg1);
1807                break;
1808            }
1809            }
1810        }
1811    };
1812
1813    static final int COLLECT_PSS_BG_MSG = 1;
1814
1815    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1816        @Override
1817        public void handleMessage(Message msg) {
1818            switch (msg.what) {
1819            case COLLECT_PSS_BG_MSG: {
1820                long start = SystemClock.uptimeMillis();
1821                MemInfoReader memInfo = null;
1822                synchronized (ActivityManagerService.this) {
1823                    if (mFullPssPending) {
1824                        mFullPssPending = false;
1825                        memInfo = new MemInfoReader();
1826                    }
1827                }
1828                if (memInfo != null) {
1829                    updateCpuStatsNow();
1830                    long nativeTotalPss = 0;
1831                    synchronized (mProcessCpuThread) {
1832                        final int N = mProcessCpuTracker.countStats();
1833                        for (int j=0; j<N; j++) {
1834                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1835                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1836                                // This is definitely an application process; skip it.
1837                                continue;
1838                            }
1839                            synchronized (mPidsSelfLocked) {
1840                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1841                                    // This is one of our own processes; skip it.
1842                                    continue;
1843                                }
1844                            }
1845                            nativeTotalPss += Debug.getPss(st.pid, null);
1846                        }
1847                    }
1848                    memInfo.readMemInfo();
1849                    synchronized (this) {
1850                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1851                                + (SystemClock.uptimeMillis()-start) + "ms");
1852                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1853                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1854                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1855                                        +memInfo.getSlabSizeKb(),
1856                                nativeTotalPss);
1857                    }
1858                }
1859
1860                int i=0, num=0;
1861                long[] tmp = new long[1];
1862                do {
1863                    ProcessRecord proc;
1864                    int procState;
1865                    int pid;
1866                    synchronized (ActivityManagerService.this) {
1867                        if (i >= mPendingPssProcesses.size()) {
1868                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1869                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1870                            mPendingPssProcesses.clear();
1871                            return;
1872                        }
1873                        proc = mPendingPssProcesses.get(i);
1874                        procState = proc.pssProcState;
1875                        if (proc.thread != null && procState == proc.setProcState) {
1876                            pid = proc.pid;
1877                        } else {
1878                            proc = null;
1879                            pid = 0;
1880                        }
1881                        i++;
1882                    }
1883                    if (proc != null) {
1884                        long pss = Debug.getPss(pid, tmp);
1885                        synchronized (ActivityManagerService.this) {
1886                            if (proc.thread != null && proc.setProcState == procState
1887                                    && proc.pid == pid) {
1888                                num++;
1889                                proc.lastPssTime = SystemClock.uptimeMillis();
1890                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1891                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1892                                        + ": " + pss + " lastPss=" + proc.lastPss
1893                                        + " state=" + ProcessList.makeProcStateString(procState));
1894                                if (proc.initialIdlePss == 0) {
1895                                    proc.initialIdlePss = pss;
1896                                }
1897                                proc.lastPss = pss;
1898                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1899                                    proc.lastCachedPss = pss;
1900                                }
1901                            }
1902                        }
1903                    }
1904                } while (true);
1905            }
1906            }
1907        }
1908    };
1909
1910    /**
1911     * Monitor for package changes and update our internal state.
1912     */
1913    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1914        @Override
1915        public void onPackageRemoved(String packageName, int uid) {
1916            // Remove all tasks with activities in the specified package from the list of recent tasks
1917            synchronized (ActivityManagerService.this) {
1918                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1919                    TaskRecord tr = mRecentTasks.get(i);
1920                    ComponentName cn = tr.intent.getComponent();
1921                    if (cn != null && cn.getPackageName().equals(packageName)) {
1922                        // If the package name matches, remove the task and kill the process
1923                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1924                    }
1925                }
1926            }
1927        }
1928
1929        @Override
1930        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1931            onPackageModified(packageName);
1932            return true;
1933        }
1934
1935        @Override
1936        public void onPackageModified(String packageName) {
1937            final PackageManager pm = mContext.getPackageManager();
1938            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1939                    new ArrayList<Pair<Intent, Integer>>();
1940            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1941            // Copy the list of recent tasks so that we don't hold onto the lock on
1942            // ActivityManagerService for long periods while checking if components exist.
1943            synchronized (ActivityManagerService.this) {
1944                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1945                    TaskRecord tr = mRecentTasks.get(i);
1946                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1947                }
1948            }
1949            // Check the recent tasks and filter out all tasks with components that no longer exist.
1950            Intent tmpI = new Intent();
1951            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1952                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1953                ComponentName cn = p.first.getComponent();
1954                if (cn != null && cn.getPackageName().equals(packageName)) {
1955                    try {
1956                        // Add the task to the list to remove if the component no longer exists
1957                        tmpI.setComponent(cn);
1958                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1959                            tasksToRemove.add(p.second);
1960                        }
1961                    } catch (Exception e) {}
1962                }
1963            }
1964            // Prune all the tasks with removed components from the list of recent tasks
1965            synchronized (ActivityManagerService.this) {
1966                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1967                    // Remove the task but don't kill the process (since other components in that
1968                    // package may still be running and in the background)
1969                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1970                }
1971            }
1972        }
1973
1974        @Override
1975        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1976            // Force stop the specified packages
1977            if (packages != null) {
1978                for (String pkg : packages) {
1979                    synchronized (ActivityManagerService.this) {
1980                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
1981                                "finished booting")) {
1982                            return true;
1983                        }
1984                    }
1985                }
1986            }
1987            return false;
1988        }
1989    };
1990
1991    public void setSystemProcess() {
1992        try {
1993            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1994            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1995            ServiceManager.addService("meminfo", new MemBinder(this));
1996            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1997            ServiceManager.addService("dbinfo", new DbBinder(this));
1998            if (MONITOR_CPU_USAGE) {
1999                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2000            }
2001            ServiceManager.addService("permission", new PermissionController(this));
2002
2003            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2004                    "android", STOCK_PM_FLAGS);
2005            mSystemThread.installSystemApplicationInfo(info);
2006
2007            synchronized (this) {
2008                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
2009                app.persistent = true;
2010                app.pid = MY_PID;
2011                app.maxAdj = ProcessList.SYSTEM_ADJ;
2012                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2013                mProcessNames.put(app.processName, app.uid, app);
2014                synchronized (mPidsSelfLocked) {
2015                    mPidsSelfLocked.put(app.pid, app);
2016                }
2017                updateLruProcessLocked(app, false, null);
2018                updateOomAdjLocked();
2019            }
2020        } catch (PackageManager.NameNotFoundException e) {
2021            throw new RuntimeException(
2022                    "Unable to find android system package", e);
2023        }
2024    }
2025
2026    public void setWindowManager(WindowManagerService wm) {
2027        mWindowManager = wm;
2028        mStackSupervisor.setWindowManager(wm);
2029    }
2030
2031    public void startObservingNativeCrashes() {
2032        final NativeCrashListener ncl = new NativeCrashListener(this);
2033        ncl.start();
2034    }
2035
2036    public IAppOpsService getAppOpsService() {
2037        return mAppOpsService;
2038    }
2039
2040    static class MemBinder extends Binder {
2041        ActivityManagerService mActivityManagerService;
2042        MemBinder(ActivityManagerService activityManagerService) {
2043            mActivityManagerService = activityManagerService;
2044        }
2045
2046        @Override
2047        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2048            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2049                    != PackageManager.PERMISSION_GRANTED) {
2050                pw.println("Permission Denial: can't dump meminfo from from pid="
2051                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2052                        + " without permission " + android.Manifest.permission.DUMP);
2053                return;
2054            }
2055
2056            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2057        }
2058    }
2059
2060    static class GraphicsBinder extends Binder {
2061        ActivityManagerService mActivityManagerService;
2062        GraphicsBinder(ActivityManagerService activityManagerService) {
2063            mActivityManagerService = activityManagerService;
2064        }
2065
2066        @Override
2067        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2068            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2069                    != PackageManager.PERMISSION_GRANTED) {
2070                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2071                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2072                        + " without permission " + android.Manifest.permission.DUMP);
2073                return;
2074            }
2075
2076            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2077        }
2078    }
2079
2080    static class DbBinder extends Binder {
2081        ActivityManagerService mActivityManagerService;
2082        DbBinder(ActivityManagerService activityManagerService) {
2083            mActivityManagerService = activityManagerService;
2084        }
2085
2086        @Override
2087        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2088            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2089                    != PackageManager.PERMISSION_GRANTED) {
2090                pw.println("Permission Denial: can't dump dbinfo from from pid="
2091                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2092                        + " without permission " + android.Manifest.permission.DUMP);
2093                return;
2094            }
2095
2096            mActivityManagerService.dumpDbInfo(fd, pw, args);
2097        }
2098    }
2099
2100    static class CpuBinder extends Binder {
2101        ActivityManagerService mActivityManagerService;
2102        CpuBinder(ActivityManagerService activityManagerService) {
2103            mActivityManagerService = activityManagerService;
2104        }
2105
2106        @Override
2107        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2108            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2109                    != PackageManager.PERMISSION_GRANTED) {
2110                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2111                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2112                        + " without permission " + android.Manifest.permission.DUMP);
2113                return;
2114            }
2115
2116            synchronized (mActivityManagerService.mProcessCpuThread) {
2117                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2118                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2119                        SystemClock.uptimeMillis()));
2120            }
2121        }
2122    }
2123
2124    public static final class Lifecycle extends SystemService {
2125        private final ActivityManagerService mService;
2126
2127        public Lifecycle(Context context) {
2128            super(context);
2129            mService = new ActivityManagerService(context);
2130        }
2131
2132        @Override
2133        public void onStart() {
2134            mService.start();
2135        }
2136
2137        public ActivityManagerService getService() {
2138            return mService;
2139        }
2140    }
2141
2142    // Note: This method is invoked on the main thread but may need to attach various
2143    // handlers to other threads.  So take care to be explicit about the looper.
2144    public ActivityManagerService(Context systemContext) {
2145        mContext = systemContext;
2146        mFactoryTest = FactoryTest.getMode();
2147        mSystemThread = ActivityThread.currentActivityThread();
2148
2149        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2150
2151        mHandlerThread = new ServiceThread(TAG,
2152                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2153        mHandlerThread.start();
2154        mHandler = new MainHandler(mHandlerThread.getLooper());
2155
2156        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2157                "foreground", BROADCAST_FG_TIMEOUT, false);
2158        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2159                "background", BROADCAST_BG_TIMEOUT, true);
2160        mBroadcastQueues[0] = mFgBroadcastQueue;
2161        mBroadcastQueues[1] = mBgBroadcastQueue;
2162
2163        mServices = new ActiveServices(this);
2164        mProviderMap = new ProviderMap(this);
2165
2166        // TODO: Move creation of battery stats service outside of activity manager service.
2167        File dataDir = Environment.getDataDirectory();
2168        File systemDir = new File(dataDir, "system");
2169        systemDir.mkdirs();
2170        mBatteryStatsService = new BatteryStatsService(new File(
2171                systemDir, "batterystats.bin").toString(), mHandler);
2172        mBatteryStatsService.getActiveStatistics().readLocked();
2173        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2174        mOnBattery = DEBUG_POWER ? true
2175                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2176        mBatteryStatsService.getActiveStatistics().setCallback(this);
2177
2178        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2179
2180        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
2181        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2182
2183        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2184
2185        // User 0 is the first and only user that runs at boot.
2186        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2187        mUserLru.add(Integer.valueOf(0));
2188        updateStartedUserArrayLocked();
2189
2190        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2191            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2192
2193        mConfiguration.setToDefaults();
2194        mConfiguration.setLocale(Locale.getDefault());
2195
2196        mConfigurationSeq = mConfiguration.seq = 1;
2197        mProcessCpuTracker.init();
2198
2199        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2200        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2201        mStackSupervisor = new ActivityStackSupervisor(this);
2202        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2203
2204        mProcessCpuThread = new Thread("CpuTracker") {
2205            @Override
2206            public void run() {
2207                while (true) {
2208                    try {
2209                        try {
2210                            synchronized(this) {
2211                                final long now = SystemClock.uptimeMillis();
2212                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2213                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2214                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2215                                //        + ", write delay=" + nextWriteDelay);
2216                                if (nextWriteDelay < nextCpuDelay) {
2217                                    nextCpuDelay = nextWriteDelay;
2218                                }
2219                                if (nextCpuDelay > 0) {
2220                                    mProcessCpuMutexFree.set(true);
2221                                    this.wait(nextCpuDelay);
2222                                }
2223                            }
2224                        } catch (InterruptedException e) {
2225                        }
2226                        updateCpuStatsNow();
2227                    } catch (Exception e) {
2228                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2229                    }
2230                }
2231            }
2232        };
2233
2234        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2235
2236        Watchdog.getInstance().addMonitor(this);
2237        Watchdog.getInstance().addThread(mHandler);
2238    }
2239
2240    public void setSystemServiceManager(SystemServiceManager mgr) {
2241        mSystemServiceManager = mgr;
2242    }
2243
2244    private void start() {
2245        mProcessCpuThread.start();
2246
2247        mBatteryStatsService.publish(mContext);
2248        mUsageStatsService.publish(mContext);
2249        mAppOpsService.publish(mContext);
2250        Slog.d("AppOps", "AppOpsService published");
2251        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2252    }
2253
2254    public void initPowerManagement() {
2255        mStackSupervisor.initPowerManagement();
2256        mBatteryStatsService.initPowerManagement();
2257    }
2258
2259    @Override
2260    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2261            throws RemoteException {
2262        if (code == SYSPROPS_TRANSACTION) {
2263            // We need to tell all apps about the system property change.
2264            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2265            synchronized(this) {
2266                final int NP = mProcessNames.getMap().size();
2267                for (int ip=0; ip<NP; ip++) {
2268                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2269                    final int NA = apps.size();
2270                    for (int ia=0; ia<NA; ia++) {
2271                        ProcessRecord app = apps.valueAt(ia);
2272                        if (app.thread != null) {
2273                            procs.add(app.thread.asBinder());
2274                        }
2275                    }
2276                }
2277            }
2278
2279            int N = procs.size();
2280            for (int i=0; i<N; i++) {
2281                Parcel data2 = Parcel.obtain();
2282                try {
2283                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2284                } catch (RemoteException e) {
2285                }
2286                data2.recycle();
2287            }
2288        }
2289        try {
2290            return super.onTransact(code, data, reply, flags);
2291        } catch (RuntimeException e) {
2292            // The activity manager only throws security exceptions, so let's
2293            // log all others.
2294            if (!(e instanceof SecurityException)) {
2295                Slog.wtf(TAG, "Activity Manager Crash", e);
2296            }
2297            throw e;
2298        }
2299    }
2300
2301    void updateCpuStats() {
2302        final long now = SystemClock.uptimeMillis();
2303        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2304            return;
2305        }
2306        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2307            synchronized (mProcessCpuThread) {
2308                mProcessCpuThread.notify();
2309            }
2310        }
2311    }
2312
2313    void updateCpuStatsNow() {
2314        synchronized (mProcessCpuThread) {
2315            mProcessCpuMutexFree.set(false);
2316            final long now = SystemClock.uptimeMillis();
2317            boolean haveNewCpuStats = false;
2318
2319            if (MONITOR_CPU_USAGE &&
2320                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2321                mLastCpuTime.set(now);
2322                haveNewCpuStats = true;
2323                mProcessCpuTracker.update();
2324                //Slog.i(TAG, mProcessCpu.printCurrentState());
2325                //Slog.i(TAG, "Total CPU usage: "
2326                //        + mProcessCpu.getTotalCpuPercent() + "%");
2327
2328                // Slog the cpu usage if the property is set.
2329                if ("true".equals(SystemProperties.get("events.cpu"))) {
2330                    int user = mProcessCpuTracker.getLastUserTime();
2331                    int system = mProcessCpuTracker.getLastSystemTime();
2332                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2333                    int irq = mProcessCpuTracker.getLastIrqTime();
2334                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2335                    int idle = mProcessCpuTracker.getLastIdleTime();
2336
2337                    int total = user + system + iowait + irq + softIrq + idle;
2338                    if (total == 0) total = 1;
2339
2340                    EventLog.writeEvent(EventLogTags.CPU,
2341                            ((user+system+iowait+irq+softIrq) * 100) / total,
2342                            (user * 100) / total,
2343                            (system * 100) / total,
2344                            (iowait * 100) / total,
2345                            (irq * 100) / total,
2346                            (softIrq * 100) / total);
2347                }
2348            }
2349
2350            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2351            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2352            synchronized(bstats) {
2353                synchronized(mPidsSelfLocked) {
2354                    if (haveNewCpuStats) {
2355                        if (mOnBattery) {
2356                            int perc = bstats.startAddingCpuLocked();
2357                            int totalUTime = 0;
2358                            int totalSTime = 0;
2359                            final int N = mProcessCpuTracker.countStats();
2360                            for (int i=0; i<N; i++) {
2361                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2362                                if (!st.working) {
2363                                    continue;
2364                                }
2365                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2366                                int otherUTime = (st.rel_utime*perc)/100;
2367                                int otherSTime = (st.rel_stime*perc)/100;
2368                                totalUTime += otherUTime;
2369                                totalSTime += otherSTime;
2370                                if (pr != null) {
2371                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2372                                    if (ps == null || !ps.isActive()) {
2373                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2374                                                pr.info.uid, pr.processName);
2375                                    }
2376                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2377                                            st.rel_stime-otherSTime);
2378                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2379                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2380                                } else {
2381                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2382                                    if (ps == null || !ps.isActive()) {
2383                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2384                                                bstats.mapUid(st.uid), st.name);
2385                                    }
2386                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2387                                            st.rel_stime-otherSTime);
2388                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2389                                }
2390                            }
2391                            bstats.finishAddingCpuLocked(perc, totalUTime,
2392                                    totalSTime, cpuSpeedTimes);
2393                        }
2394                    }
2395                }
2396
2397                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2398                    mLastWriteTime = now;
2399                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2400                }
2401            }
2402        }
2403    }
2404
2405    @Override
2406    public void batteryNeedsCpuUpdate() {
2407        updateCpuStatsNow();
2408    }
2409
2410    @Override
2411    public void batteryPowerChanged(boolean onBattery) {
2412        // When plugging in, update the CPU stats first before changing
2413        // the plug state.
2414        updateCpuStatsNow();
2415        synchronized (this) {
2416            synchronized(mPidsSelfLocked) {
2417                mOnBattery = DEBUG_POWER ? true : onBattery;
2418            }
2419        }
2420    }
2421
2422    /**
2423     * Initialize the application bind args. These are passed to each
2424     * process when the bindApplication() IPC is sent to the process. They're
2425     * lazily setup to make sure the services are running when they're asked for.
2426     */
2427    private HashMap<String, IBinder> getCommonServicesLocked() {
2428        if (mAppBindArgs == null) {
2429            mAppBindArgs = new HashMap<String, IBinder>();
2430
2431            // Setup the application init args
2432            mAppBindArgs.put("package", ServiceManager.getService("package"));
2433            mAppBindArgs.put("window", ServiceManager.getService("window"));
2434            mAppBindArgs.put(Context.ALARM_SERVICE,
2435                    ServiceManager.getService(Context.ALARM_SERVICE));
2436        }
2437        return mAppBindArgs;
2438    }
2439
2440    final void setFocusedActivityLocked(ActivityRecord r) {
2441        if (mFocusedActivity != r) {
2442            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2443            mFocusedActivity = r;
2444            if (r.task != null && r.task.voiceInteractor != null) {
2445                startRunningVoiceLocked();
2446            } else {
2447                finishRunningVoiceLocked();
2448            }
2449            mStackSupervisor.setFocusedStack(r);
2450            if (r != null) {
2451                mWindowManager.setFocusedApp(r.appToken, true);
2452            }
2453            applyUpdateLockStateLocked(r);
2454        }
2455    }
2456
2457    final void clearFocusedActivity(ActivityRecord r) {
2458        if (mFocusedActivity == r) {
2459            mFocusedActivity = null;
2460        }
2461    }
2462
2463    @Override
2464    public void setFocusedStack(int stackId) {
2465        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2466        synchronized (ActivityManagerService.this) {
2467            ActivityStack stack = mStackSupervisor.getStack(stackId);
2468            if (stack != null) {
2469                ActivityRecord r = stack.topRunningActivityLocked(null);
2470                if (r != null) {
2471                    setFocusedActivityLocked(r);
2472                }
2473            }
2474        }
2475    }
2476
2477    @Override
2478    public void notifyActivityDrawn(IBinder token) {
2479        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2480        synchronized (this) {
2481            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2482            if (r != null) {
2483                r.task.stack.notifyActivityDrawnLocked(r);
2484            }
2485        }
2486    }
2487
2488    final void applyUpdateLockStateLocked(ActivityRecord r) {
2489        // Modifications to the UpdateLock state are done on our handler, outside
2490        // the activity manager's locks.  The new state is determined based on the
2491        // state *now* of the relevant activity record.  The object is passed to
2492        // the handler solely for logging detail, not to be consulted/modified.
2493        final boolean nextState = r != null && r.immersive;
2494        mHandler.sendMessage(
2495                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2496    }
2497
2498    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2499        Message msg = Message.obtain();
2500        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2501        msg.obj = r.task.askedCompatMode ? null : r;
2502        mHandler.sendMessage(msg);
2503    }
2504
2505    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2506            String what, Object obj, ProcessRecord srcApp) {
2507        app.lastActivityTime = now;
2508
2509        if (app.activities.size() > 0) {
2510            // Don't want to touch dependent processes that are hosting activities.
2511            return index;
2512        }
2513
2514        int lrui = mLruProcesses.lastIndexOf(app);
2515        if (lrui < 0) {
2516            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2517                    + what + " " + obj + " from " + srcApp);
2518            return index;
2519        }
2520
2521        if (lrui >= index) {
2522            // Don't want to cause this to move dependent processes *back* in the
2523            // list as if they were less frequently used.
2524            return index;
2525        }
2526
2527        if (lrui >= mLruProcessActivityStart) {
2528            // Don't want to touch dependent processes that are hosting activities.
2529            return index;
2530        }
2531
2532        mLruProcesses.remove(lrui);
2533        if (index > 0) {
2534            index--;
2535        }
2536        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2537                + " in LRU list: " + app);
2538        mLruProcesses.add(index, app);
2539        return index;
2540    }
2541
2542    final void removeLruProcessLocked(ProcessRecord app) {
2543        int lrui = mLruProcesses.lastIndexOf(app);
2544        if (lrui >= 0) {
2545            if (lrui <= mLruProcessActivityStart) {
2546                mLruProcessActivityStart--;
2547            }
2548            if (lrui <= mLruProcessServiceStart) {
2549                mLruProcessServiceStart--;
2550            }
2551            mLruProcesses.remove(lrui);
2552        }
2553    }
2554
2555    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2556            ProcessRecord client) {
2557        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2558                || app.treatLikeActivity;
2559        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2560        if (!activityChange && hasActivity) {
2561            // The process has activities, so we are only allowing activity-based adjustments
2562            // to move it.  It should be kept in the front of the list with other
2563            // processes that have activities, and we don't want those to change their
2564            // order except due to activity operations.
2565            return;
2566        }
2567
2568        mLruSeq++;
2569        final long now = SystemClock.uptimeMillis();
2570        app.lastActivityTime = now;
2571
2572        // First a quick reject: if the app is already at the position we will
2573        // put it, then there is nothing to do.
2574        if (hasActivity) {
2575            final int N = mLruProcesses.size();
2576            if (N > 0 && mLruProcesses.get(N-1) == app) {
2577                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2578                return;
2579            }
2580        } else {
2581            if (mLruProcessServiceStart > 0
2582                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2583                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2584                return;
2585            }
2586        }
2587
2588        int lrui = mLruProcesses.lastIndexOf(app);
2589
2590        if (app.persistent && lrui >= 0) {
2591            // We don't care about the position of persistent processes, as long as
2592            // they are in the list.
2593            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2594            return;
2595        }
2596
2597        /* In progress: compute new position first, so we can avoid doing work
2598           if the process is not actually going to move.  Not yet working.
2599        int addIndex;
2600        int nextIndex;
2601        boolean inActivity = false, inService = false;
2602        if (hasActivity) {
2603            // Process has activities, put it at the very tipsy-top.
2604            addIndex = mLruProcesses.size();
2605            nextIndex = mLruProcessServiceStart;
2606            inActivity = true;
2607        } else if (hasService) {
2608            // Process has services, put it at the top of the service list.
2609            addIndex = mLruProcessActivityStart;
2610            nextIndex = mLruProcessServiceStart;
2611            inActivity = true;
2612            inService = true;
2613        } else  {
2614            // Process not otherwise of interest, it goes to the top of the non-service area.
2615            addIndex = mLruProcessServiceStart;
2616            if (client != null) {
2617                int clientIndex = mLruProcesses.lastIndexOf(client);
2618                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2619                        + app);
2620                if (clientIndex >= 0 && addIndex > clientIndex) {
2621                    addIndex = clientIndex;
2622                }
2623            }
2624            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2625        }
2626
2627        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2628                + mLruProcessActivityStart + "): " + app);
2629        */
2630
2631        if (lrui >= 0) {
2632            if (lrui < mLruProcessActivityStart) {
2633                mLruProcessActivityStart--;
2634            }
2635            if (lrui < mLruProcessServiceStart) {
2636                mLruProcessServiceStart--;
2637            }
2638            /*
2639            if (addIndex > lrui) {
2640                addIndex--;
2641            }
2642            if (nextIndex > lrui) {
2643                nextIndex--;
2644            }
2645            */
2646            mLruProcesses.remove(lrui);
2647        }
2648
2649        /*
2650        mLruProcesses.add(addIndex, app);
2651        if (inActivity) {
2652            mLruProcessActivityStart++;
2653        }
2654        if (inService) {
2655            mLruProcessActivityStart++;
2656        }
2657        */
2658
2659        int nextIndex;
2660        if (hasActivity) {
2661            final int N = mLruProcesses.size();
2662            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2663                // Process doesn't have activities, but has clients with
2664                // activities...  move it up, but one below the top (the top
2665                // should always have a real activity).
2666                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2667                mLruProcesses.add(N-1, app);
2668                // To keep it from spamming the LRU list (by making a bunch of clients),
2669                // we will push down any other entries owned by the app.
2670                final int uid = app.info.uid;
2671                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2672                    ProcessRecord subProc = mLruProcesses.get(i);
2673                    if (subProc.info.uid == uid) {
2674                        // We want to push this one down the list.  If the process after
2675                        // it is for the same uid, however, don't do so, because we don't
2676                        // want them internally to be re-ordered.
2677                        if (mLruProcesses.get(i-1).info.uid != uid) {
2678                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2679                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2680                            ProcessRecord tmp = mLruProcesses.get(i);
2681                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2682                            mLruProcesses.set(i-1, tmp);
2683                            i--;
2684                        }
2685                    } else {
2686                        // A gap, we can stop here.
2687                        break;
2688                    }
2689                }
2690            } else {
2691                // Process has activities, put it at the very tipsy-top.
2692                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2693                mLruProcesses.add(app);
2694            }
2695            nextIndex = mLruProcessServiceStart;
2696        } else if (hasService) {
2697            // Process has services, put it at the top of the service list.
2698            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2699            mLruProcesses.add(mLruProcessActivityStart, app);
2700            nextIndex = mLruProcessServiceStart;
2701            mLruProcessActivityStart++;
2702        } else  {
2703            // Process not otherwise of interest, it goes to the top of the non-service area.
2704            int index = mLruProcessServiceStart;
2705            if (client != null) {
2706                // If there is a client, don't allow the process to be moved up higher
2707                // in the list than that client.
2708                int clientIndex = mLruProcesses.lastIndexOf(client);
2709                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2710                        + " when updating " + app);
2711                if (clientIndex <= lrui) {
2712                    // Don't allow the client index restriction to push it down farther in the
2713                    // list than it already is.
2714                    clientIndex = lrui;
2715                }
2716                if (clientIndex >= 0 && index > clientIndex) {
2717                    index = clientIndex;
2718                }
2719            }
2720            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2721            mLruProcesses.add(index, app);
2722            nextIndex = index-1;
2723            mLruProcessActivityStart++;
2724            mLruProcessServiceStart++;
2725        }
2726
2727        // If the app is currently using a content provider or service,
2728        // bump those processes as well.
2729        for (int j=app.connections.size()-1; j>=0; j--) {
2730            ConnectionRecord cr = app.connections.valueAt(j);
2731            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2732                    && cr.binding.service.app != null
2733                    && cr.binding.service.app.lruSeq != mLruSeq
2734                    && !cr.binding.service.app.persistent) {
2735                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2736                        "service connection", cr, app);
2737            }
2738        }
2739        for (int j=app.conProviders.size()-1; j>=0; j--) {
2740            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2741            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2742                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2743                        "provider reference", cpr, app);
2744            }
2745        }
2746    }
2747
2748    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2749        if (uid == Process.SYSTEM_UID) {
2750            // The system gets to run in any process.  If there are multiple
2751            // processes with the same uid, just pick the first (this
2752            // should never happen).
2753            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2754            if (procs == null) return null;
2755            final int N = procs.size();
2756            for (int i = 0; i < N; i++) {
2757                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2758            }
2759        }
2760        ProcessRecord proc = mProcessNames.get(processName, uid);
2761        if (false && proc != null && !keepIfLarge
2762                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2763                && proc.lastCachedPss >= 4000) {
2764            // Turn this condition on to cause killing to happen regularly, for testing.
2765            if (proc.baseProcessTracker != null) {
2766                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2767            }
2768            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2769                    + "k from cached");
2770        } else if (proc != null && !keepIfLarge
2771                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2772                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2773            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2774            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2775                if (proc.baseProcessTracker != null) {
2776                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2777                }
2778                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2779                        + "k from cached");
2780            }
2781        }
2782        return proc;
2783    }
2784
2785    void ensurePackageDexOpt(String packageName) {
2786        IPackageManager pm = AppGlobals.getPackageManager();
2787        try {
2788            if (pm.performDexOpt(packageName)) {
2789                mDidDexOpt = true;
2790            }
2791        } catch (RemoteException e) {
2792        }
2793    }
2794
2795    boolean isNextTransitionForward() {
2796        int transit = mWindowManager.getPendingAppTransition();
2797        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2798                || transit == AppTransition.TRANSIT_TASK_OPEN
2799                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2800    }
2801
2802    final ProcessRecord startProcessLocked(String processName,
2803            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2804            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2805            boolean isolated, boolean keepIfLarge) {
2806        ProcessRecord app;
2807        if (!isolated) {
2808            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2809        } else {
2810            // If this is an isolated process, it can't re-use an existing process.
2811            app = null;
2812        }
2813        // We don't have to do anything more if:
2814        // (1) There is an existing application record; and
2815        // (2) The caller doesn't think it is dead, OR there is no thread
2816        //     object attached to it so we know it couldn't have crashed; and
2817        // (3) There is a pid assigned to it, so it is either starting or
2818        //     already running.
2819        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2820                + " app=" + app + " knownToBeDead=" + knownToBeDead
2821                + " thread=" + (app != null ? app.thread : null)
2822                + " pid=" + (app != null ? app.pid : -1));
2823        if (app != null && app.pid > 0) {
2824            if (!knownToBeDead || app.thread == null) {
2825                // We already have the app running, or are waiting for it to
2826                // come up (we have a pid but not yet its thread), so keep it.
2827                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2828                // If this is a new package in the process, add the package to the list
2829                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2830                return app;
2831            }
2832
2833            // An application record is attached to a previous process,
2834            // clean it up now.
2835            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2836            handleAppDiedLocked(app, true, true);
2837        }
2838
2839        String hostingNameStr = hostingName != null
2840                ? hostingName.flattenToShortString() : null;
2841
2842        if (!isolated) {
2843            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2844                // If we are in the background, then check to see if this process
2845                // is bad.  If so, we will just silently fail.
2846                if (mBadProcesses.get(info.processName, info.uid) != null) {
2847                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2848                            + "/" + info.processName);
2849                    return null;
2850                }
2851            } else {
2852                // When the user is explicitly starting a process, then clear its
2853                // crash count so that we won't make it bad until they see at
2854                // least one crash dialog again, and make the process good again
2855                // if it had been bad.
2856                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2857                        + "/" + info.processName);
2858                mProcessCrashTimes.remove(info.processName, info.uid);
2859                if (mBadProcesses.get(info.processName, info.uid) != null) {
2860                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2861                            UserHandle.getUserId(info.uid), info.uid,
2862                            info.processName);
2863                    mBadProcesses.remove(info.processName, info.uid);
2864                    if (app != null) {
2865                        app.bad = false;
2866                    }
2867                }
2868            }
2869        }
2870
2871        if (app == null) {
2872            app = newProcessRecordLocked(info, processName, isolated);
2873            if (app == null) {
2874                Slog.w(TAG, "Failed making new process record for "
2875                        + processName + "/" + info.uid + " isolated=" + isolated);
2876                return null;
2877            }
2878            mProcessNames.put(processName, app.uid, app);
2879            if (isolated) {
2880                mIsolatedProcesses.put(app.uid, app);
2881            }
2882        } else {
2883            // If this is a new package in the process, add the package to the list
2884            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2885        }
2886
2887        // If the system is not ready yet, then hold off on starting this
2888        // process until it is.
2889        if (!mProcessesReady
2890                && !isAllowedWhileBooting(info)
2891                && !allowWhileBooting) {
2892            if (!mProcessesOnHold.contains(app)) {
2893                mProcessesOnHold.add(app);
2894            }
2895            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2896            return app;
2897        }
2898
2899        startProcessLocked(app, hostingType, hostingNameStr, null /* ABI override */);
2900        return (app.pid != 0) ? app : null;
2901    }
2902
2903    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2904        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2905    }
2906
2907    private final void startProcessLocked(ProcessRecord app,
2908            String hostingType, String hostingNameStr, String abiOverride) {
2909        if (app.pid > 0 && app.pid != MY_PID) {
2910            synchronized (mPidsSelfLocked) {
2911                mPidsSelfLocked.remove(app.pid);
2912                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2913            }
2914            app.setPid(0);
2915        }
2916
2917        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2918                "startProcessLocked removing on hold: " + app);
2919        mProcessesOnHold.remove(app);
2920
2921        updateCpuStats();
2922
2923        try {
2924            int uid = app.uid;
2925
2926            int[] gids = null;
2927            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2928            if (!app.isolated) {
2929                int[] permGids = null;
2930                try {
2931                    final PackageManager pm = mContext.getPackageManager();
2932                    permGids = pm.getPackageGids(app.info.packageName);
2933
2934                    if (Environment.isExternalStorageEmulated()) {
2935                        if (pm.checkPermission(
2936                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2937                                app.info.packageName) == PERMISSION_GRANTED) {
2938                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2939                        } else {
2940                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2941                        }
2942                    }
2943                } catch (PackageManager.NameNotFoundException e) {
2944                    Slog.w(TAG, "Unable to retrieve gids", e);
2945                }
2946
2947                /*
2948                 * Add shared application and profile GIDs so applications can share some
2949                 * resources like shared libraries and access user-wide resources
2950                 */
2951                if (permGids == null) {
2952                    gids = new int[2];
2953                } else {
2954                    gids = new int[permGids.length + 2];
2955                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2956                }
2957                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2958                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2959            }
2960            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2961                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2962                        && mTopComponent != null
2963                        && app.processName.equals(mTopComponent.getPackageName())) {
2964                    uid = 0;
2965                }
2966                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2967                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2968                    uid = 0;
2969                }
2970            }
2971            int debugFlags = 0;
2972            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2973                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2974                // Also turn on CheckJNI for debuggable apps. It's quite
2975                // awkward to turn on otherwise.
2976                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2977            }
2978            // Run the app in safe mode if its manifest requests so or the
2979            // system is booted in safe mode.
2980            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2981                mSafeMode == true) {
2982                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2983            }
2984            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2985                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2986            }
2987            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2988                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2989            }
2990            if ("1".equals(SystemProperties.get("debug.assert"))) {
2991                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2992            }
2993
2994            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.cpuAbi;
2995            if (requiredAbi == null) {
2996                requiredAbi = Build.SUPPORTED_ABIS[0];
2997            }
2998
2999            // Start the process.  It will either succeed and return a result containing
3000            // the PID of the new process, or else throw a RuntimeException.
3001            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
3002                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3003                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
3004
3005            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
3006            synchronized (bs) {
3007                if (bs.isOnBattery()) {
3008                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
3009                }
3010            }
3011
3012            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3013                    UserHandle.getUserId(uid), startResult.pid, uid,
3014                    app.processName, hostingType,
3015                    hostingNameStr != null ? hostingNameStr : "");
3016
3017            if (app.persistent) {
3018                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3019            }
3020
3021            StringBuilder buf = mStringBuilder;
3022            buf.setLength(0);
3023            buf.append("Start proc ");
3024            buf.append(app.processName);
3025            buf.append(" for ");
3026            buf.append(hostingType);
3027            if (hostingNameStr != null) {
3028                buf.append(" ");
3029                buf.append(hostingNameStr);
3030            }
3031            buf.append(": pid=");
3032            buf.append(startResult.pid);
3033            buf.append(" uid=");
3034            buf.append(uid);
3035            buf.append(" gids={");
3036            if (gids != null) {
3037                for (int gi=0; gi<gids.length; gi++) {
3038                    if (gi != 0) buf.append(", ");
3039                    buf.append(gids[gi]);
3040
3041                }
3042            }
3043            buf.append("}");
3044            if (requiredAbi != null) {
3045                buf.append(" abi=");
3046                buf.append(requiredAbi);
3047            }
3048            Slog.i(TAG, buf.toString());
3049            app.setPid(startResult.pid);
3050            app.usingWrapper = startResult.usingWrapper;
3051            app.removed = false;
3052            synchronized (mPidsSelfLocked) {
3053                this.mPidsSelfLocked.put(startResult.pid, app);
3054                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3055                msg.obj = app;
3056                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3057                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3058            }
3059            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
3060                    app.processName, app.info.uid);
3061            if (app.isolated) {
3062                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3063            }
3064        } catch (RuntimeException e) {
3065            // XXX do better error recovery.
3066            app.setPid(0);
3067            Slog.e(TAG, "Failure starting process " + app.processName, e);
3068        }
3069    }
3070
3071    void updateUsageStats(ActivityRecord component, boolean resumed) {
3072        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3073        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3074        if (resumed) {
3075            mUsageStatsService.noteResumeComponent(component.realActivity);
3076            synchronized (stats) {
3077                stats.noteActivityResumedLocked(component.app.uid);
3078            }
3079        } else {
3080            mUsageStatsService.notePauseComponent(component.realActivity);
3081            synchronized (stats) {
3082                stats.noteActivityPausedLocked(component.app.uid);
3083            }
3084        }
3085    }
3086
3087    Intent getHomeIntent() {
3088        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3089        intent.setComponent(mTopComponent);
3090        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3091            intent.addCategory(Intent.CATEGORY_HOME);
3092        }
3093        return intent;
3094    }
3095
3096    boolean startHomeActivityLocked(int userId) {
3097        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3098                && mTopAction == null) {
3099            // We are running in factory test mode, but unable to find
3100            // the factory test app, so just sit around displaying the
3101            // error message and don't try to start anything.
3102            return false;
3103        }
3104        Intent intent = getHomeIntent();
3105        ActivityInfo aInfo =
3106            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3107        if (aInfo != null) {
3108            intent.setComponent(new ComponentName(
3109                    aInfo.applicationInfo.packageName, aInfo.name));
3110            // Don't do this if the home app is currently being
3111            // instrumented.
3112            aInfo = new ActivityInfo(aInfo);
3113            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3114            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3115                    aInfo.applicationInfo.uid, true);
3116            if (app == null || app.instrumentationClass == null) {
3117                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3118                mStackSupervisor.startHomeActivity(intent, aInfo);
3119            }
3120        }
3121
3122        return true;
3123    }
3124
3125    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3126        ActivityInfo ai = null;
3127        ComponentName comp = intent.getComponent();
3128        try {
3129            if (comp != null) {
3130                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3131            } else {
3132                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3133                        intent,
3134                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3135                            flags, userId);
3136
3137                if (info != null) {
3138                    ai = info.activityInfo;
3139                }
3140            }
3141        } catch (RemoteException e) {
3142            // ignore
3143        }
3144
3145        return ai;
3146    }
3147
3148    /**
3149     * Starts the "new version setup screen" if appropriate.
3150     */
3151    void startSetupActivityLocked() {
3152        // Only do this once per boot.
3153        if (mCheckedForSetup) {
3154            return;
3155        }
3156
3157        // We will show this screen if the current one is a different
3158        // version than the last one shown, and we are not running in
3159        // low-level factory test mode.
3160        final ContentResolver resolver = mContext.getContentResolver();
3161        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3162                Settings.Global.getInt(resolver,
3163                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3164            mCheckedForSetup = true;
3165
3166            // See if we should be showing the platform update setup UI.
3167            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3168            List<ResolveInfo> ris = mContext.getPackageManager()
3169                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3170
3171            // We don't allow third party apps to replace this.
3172            ResolveInfo ri = null;
3173            for (int i=0; ris != null && i<ris.size(); i++) {
3174                if ((ris.get(i).activityInfo.applicationInfo.flags
3175                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3176                    ri = ris.get(i);
3177                    break;
3178                }
3179            }
3180
3181            if (ri != null) {
3182                String vers = ri.activityInfo.metaData != null
3183                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3184                        : null;
3185                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3186                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3187                            Intent.METADATA_SETUP_VERSION);
3188                }
3189                String lastVers = Settings.Secure.getString(
3190                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3191                if (vers != null && !vers.equals(lastVers)) {
3192                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3193                    intent.setComponent(new ComponentName(
3194                            ri.activityInfo.packageName, ri.activityInfo.name));
3195                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3196                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3197                }
3198            }
3199        }
3200    }
3201
3202    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3203        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3204    }
3205
3206    void enforceNotIsolatedCaller(String caller) {
3207        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3208            throw new SecurityException("Isolated process not allowed to call " + caller);
3209        }
3210    }
3211
3212    @Override
3213    public int getFrontActivityScreenCompatMode() {
3214        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3215        synchronized (this) {
3216            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3217        }
3218    }
3219
3220    @Override
3221    public void setFrontActivityScreenCompatMode(int mode) {
3222        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3223                "setFrontActivityScreenCompatMode");
3224        synchronized (this) {
3225            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3226        }
3227    }
3228
3229    @Override
3230    public int getPackageScreenCompatMode(String packageName) {
3231        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3232        synchronized (this) {
3233            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3234        }
3235    }
3236
3237    @Override
3238    public void setPackageScreenCompatMode(String packageName, int mode) {
3239        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3240                "setPackageScreenCompatMode");
3241        synchronized (this) {
3242            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3243        }
3244    }
3245
3246    @Override
3247    public boolean getPackageAskScreenCompat(String packageName) {
3248        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3249        synchronized (this) {
3250            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3251        }
3252    }
3253
3254    @Override
3255    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3256        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3257                "setPackageAskScreenCompat");
3258        synchronized (this) {
3259            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3260        }
3261    }
3262
3263    private void dispatchProcessesChanged() {
3264        int N;
3265        synchronized (this) {
3266            N = mPendingProcessChanges.size();
3267            if (mActiveProcessChanges.length < N) {
3268                mActiveProcessChanges = new ProcessChangeItem[N];
3269            }
3270            mPendingProcessChanges.toArray(mActiveProcessChanges);
3271            mAvailProcessChanges.addAll(mPendingProcessChanges);
3272            mPendingProcessChanges.clear();
3273            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3274        }
3275
3276        int i = mProcessObservers.beginBroadcast();
3277        while (i > 0) {
3278            i--;
3279            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3280            if (observer != null) {
3281                try {
3282                    for (int j=0; j<N; j++) {
3283                        ProcessChangeItem item = mActiveProcessChanges[j];
3284                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3285                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3286                                    + item.pid + " uid=" + item.uid + ": "
3287                                    + item.foregroundActivities);
3288                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3289                                    item.foregroundActivities);
3290                        }
3291                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3292                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3293                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3294                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3295                        }
3296                    }
3297                } catch (RemoteException e) {
3298                }
3299            }
3300        }
3301        mProcessObservers.finishBroadcast();
3302    }
3303
3304    private void dispatchProcessDied(int pid, int uid) {
3305        int i = mProcessObservers.beginBroadcast();
3306        while (i > 0) {
3307            i--;
3308            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3309            if (observer != null) {
3310                try {
3311                    observer.onProcessDied(pid, uid);
3312                } catch (RemoteException e) {
3313                }
3314            }
3315        }
3316        mProcessObservers.finishBroadcast();
3317    }
3318
3319    final void doPendingActivityLaunchesLocked(boolean doResume) {
3320        final int N = mPendingActivityLaunches.size();
3321        if (N <= 0) {
3322            return;
3323        }
3324        for (int i=0; i<N; i++) {
3325            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3326            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
3327                    doResume && i == (N-1), null);
3328        }
3329        mPendingActivityLaunches.clear();
3330    }
3331
3332    @Override
3333    public final int startActivity(IApplicationThread caller, String callingPackage,
3334            Intent intent, String resolvedType, IBinder resultTo,
3335            String resultWho, int requestCode, int startFlags,
3336            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3337        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3338                resultWho, requestCode,
3339                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3340    }
3341
3342    @Override
3343    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3344            Intent intent, String resolvedType, IBinder resultTo,
3345            String resultWho, int requestCode, int startFlags,
3346            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3347        enforceNotIsolatedCaller("startActivity");
3348        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3349                false, true, "startActivity", null);
3350        // TODO: Switch to user app stacks here.
3351        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3352                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3353                null, null, options, userId, null);
3354    }
3355
3356    @Override
3357    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3358            Intent intent, String resolvedType, IBinder resultTo,
3359            String resultWho, int requestCode, int startFlags, String profileFile,
3360            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3361        enforceNotIsolatedCaller("startActivityAndWait");
3362        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3363                false, true, "startActivityAndWait", null);
3364        WaitResult res = new WaitResult();
3365        // TODO: Switch to user app stacks here.
3366        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3367                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3368                res, null, options, UserHandle.getCallingUserId(), null);
3369        return res;
3370    }
3371
3372    @Override
3373    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3374            Intent intent, String resolvedType, IBinder resultTo,
3375            String resultWho, int requestCode, int startFlags, Configuration config,
3376            Bundle options, int userId) {
3377        enforceNotIsolatedCaller("startActivityWithConfig");
3378        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3379                false, true, "startActivityWithConfig", null);
3380        // TODO: Switch to user app stacks here.
3381        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3382                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3383                null, null, null, config, options, userId, null);
3384        return ret;
3385    }
3386
3387    @Override
3388    public int startActivityIntentSender(IApplicationThread caller,
3389            IntentSender intent, Intent fillInIntent, String resolvedType,
3390            IBinder resultTo, String resultWho, int requestCode,
3391            int flagsMask, int flagsValues, Bundle options) {
3392        enforceNotIsolatedCaller("startActivityIntentSender");
3393        // Refuse possible leaked file descriptors
3394        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3395            throw new IllegalArgumentException("File descriptors passed in Intent");
3396        }
3397
3398        IIntentSender sender = intent.getTarget();
3399        if (!(sender instanceof PendingIntentRecord)) {
3400            throw new IllegalArgumentException("Bad PendingIntent object");
3401        }
3402
3403        PendingIntentRecord pir = (PendingIntentRecord)sender;
3404
3405        synchronized (this) {
3406            // If this is coming from the currently resumed activity, it is
3407            // effectively saying that app switches are allowed at this point.
3408            final ActivityStack stack = getFocusedStack();
3409            if (stack.mResumedActivity != null &&
3410                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3411                mAppSwitchesAllowedTime = 0;
3412            }
3413        }
3414        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3415                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3416        return ret;
3417    }
3418
3419    @Override
3420    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3421            Intent intent, String resolvedType, IVoiceInteractionSession session,
3422            IVoiceInteractor interactor, int startFlags, String profileFile,
3423            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3424        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3425                != PackageManager.PERMISSION_GRANTED) {
3426            String msg = "Permission Denial: startVoiceActivity() from pid="
3427                    + Binder.getCallingPid()
3428                    + ", uid=" + Binder.getCallingUid()
3429                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3430            Slog.w(TAG, msg);
3431            throw new SecurityException(msg);
3432        }
3433        if (session == null || interactor == null) {
3434            throw new NullPointerException("null session or interactor");
3435        }
3436        userId = handleIncomingUser(callingPid, callingUid, userId,
3437                false, true, "startVoiceActivity", null);
3438        // TODO: Switch to user app stacks here.
3439        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3440                resolvedType, session, interactor, null, null, 0, startFlags,
3441                profileFile, profileFd, null, null, options, userId, null);
3442    }
3443
3444    @Override
3445    public boolean startNextMatchingActivity(IBinder callingActivity,
3446            Intent intent, Bundle options) {
3447        // Refuse possible leaked file descriptors
3448        if (intent != null && intent.hasFileDescriptors() == true) {
3449            throw new IllegalArgumentException("File descriptors passed in Intent");
3450        }
3451
3452        synchronized (this) {
3453            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3454            if (r == null) {
3455                ActivityOptions.abort(options);
3456                return false;
3457            }
3458            if (r.app == null || r.app.thread == null) {
3459                // The caller is not running...  d'oh!
3460                ActivityOptions.abort(options);
3461                return false;
3462            }
3463            intent = new Intent(intent);
3464            // The caller is not allowed to change the data.
3465            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3466            // And we are resetting to find the next component...
3467            intent.setComponent(null);
3468
3469            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3470
3471            ActivityInfo aInfo = null;
3472            try {
3473                List<ResolveInfo> resolves =
3474                    AppGlobals.getPackageManager().queryIntentActivities(
3475                            intent, r.resolvedType,
3476                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3477                            UserHandle.getCallingUserId());
3478
3479                // Look for the original activity in the list...
3480                final int N = resolves != null ? resolves.size() : 0;
3481                for (int i=0; i<N; i++) {
3482                    ResolveInfo rInfo = resolves.get(i);
3483                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3484                            && rInfo.activityInfo.name.equals(r.info.name)) {
3485                        // We found the current one...  the next matching is
3486                        // after it.
3487                        i++;
3488                        if (i<N) {
3489                            aInfo = resolves.get(i).activityInfo;
3490                        }
3491                        if (debug) {
3492                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3493                                    + "/" + r.info.name);
3494                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3495                                    + "/" + aInfo.name);
3496                        }
3497                        break;
3498                    }
3499                }
3500            } catch (RemoteException e) {
3501            }
3502
3503            if (aInfo == null) {
3504                // Nobody who is next!
3505                ActivityOptions.abort(options);
3506                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3507                return false;
3508            }
3509
3510            intent.setComponent(new ComponentName(
3511                    aInfo.applicationInfo.packageName, aInfo.name));
3512            intent.setFlags(intent.getFlags()&~(
3513                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3514                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3515                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3516                    Intent.FLAG_ACTIVITY_NEW_TASK));
3517
3518            // Okay now we need to start the new activity, replacing the
3519            // currently running activity.  This is a little tricky because
3520            // we want to start the new one as if the current one is finished,
3521            // but not finish the current one first so that there is no flicker.
3522            // And thus...
3523            final boolean wasFinishing = r.finishing;
3524            r.finishing = true;
3525
3526            // Propagate reply information over to the new activity.
3527            final ActivityRecord resultTo = r.resultTo;
3528            final String resultWho = r.resultWho;
3529            final int requestCode = r.requestCode;
3530            r.resultTo = null;
3531            if (resultTo != null) {
3532                resultTo.removeResultsLocked(r, resultWho, requestCode);
3533            }
3534
3535            final long origId = Binder.clearCallingIdentity();
3536            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3537                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3538                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3539                    options, false, null, null);
3540            Binder.restoreCallingIdentity(origId);
3541
3542            r.finishing = wasFinishing;
3543            if (res != ActivityManager.START_SUCCESS) {
3544                return false;
3545            }
3546            return true;
3547        }
3548    }
3549
3550    final int startActivityInPackage(int uid, String callingPackage,
3551            Intent intent, String resolvedType, IBinder resultTo,
3552            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3553                    IActivityContainer container) {
3554
3555        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3556                false, true, "startActivityInPackage", null);
3557
3558        // TODO: Switch to user app stacks here.
3559        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3560                null, null, resultTo, resultWho, requestCode, startFlags,
3561                null, null, null, null, options, userId, container);
3562        return ret;
3563    }
3564
3565    @Override
3566    public final int startActivities(IApplicationThread caller, String callingPackage,
3567            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3568            int userId) {
3569        enforceNotIsolatedCaller("startActivities");
3570        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3571                false, true, "startActivity", null);
3572        // TODO: Switch to user app stacks here.
3573        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3574                resolvedTypes, resultTo, options, userId);
3575        return ret;
3576    }
3577
3578    final int startActivitiesInPackage(int uid, String callingPackage,
3579            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3580            Bundle options, int userId) {
3581
3582        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3583                false, true, "startActivityInPackage", null);
3584        // TODO: Switch to user app stacks here.
3585        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3586                resultTo, options, userId);
3587        return ret;
3588    }
3589
3590    final void addRecentTaskLocked(TaskRecord task) {
3591        int N = mRecentTasks.size();
3592        // Quick case: check if the top-most recent task is the same.
3593        if (N > 0 && mRecentTasks.get(0) == task) {
3594            return;
3595        }
3596        // Another quick case: never add voice sessions.
3597        if (task.voiceSession != null) {
3598            return;
3599        }
3600        // Remove any existing entries that are the same kind of task.
3601        final Intent intent = task.intent;
3602        final boolean document = intent != null && intent.isDocument();
3603        final ComponentName comp = intent.getComponent();
3604
3605        int maxRecents = task.maxRecents - 1;
3606        for (int i=0; i<N; i++) {
3607            TaskRecord tr = mRecentTasks.get(i);
3608            if (task != tr) {
3609                if (task.userId != tr.userId) {
3610                    continue;
3611                }
3612                final Intent trIntent = tr.intent;
3613                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3614                    (intent == null || !intent.filterEquals(trIntent))) {
3615                    continue;
3616                }
3617                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3618                if (document && trIsDocument) {
3619                    // These are the same document activity (not necessarily the same doc).
3620                    if (maxRecents > 0) {
3621                        --maxRecents;
3622                        continue;
3623                    }
3624                    // Hit the maximum number of documents for this task. Fall through
3625                    // and remove this document from recents.
3626                } else if (document || trIsDocument) {
3627                    // Only one of these is a document. Not the droid we're looking for.
3628                    continue;
3629                }
3630            }
3631
3632            // Either task and tr are the same or, their affinities match or their intents match
3633            // and neither of them is a document, or they are documents using the same activity
3634            // and their maxRecents has been reached.
3635            tr.disposeThumbnail();
3636            mRecentTasks.remove(i);
3637            i--;
3638            N--;
3639            if (task.intent == null) {
3640                // If the new recent task we are adding is not fully
3641                // specified, then replace it with the existing recent task.
3642                task = tr;
3643            }
3644            mTaskPersister.notify(tr, false);
3645        }
3646        if (N >= MAX_RECENT_TASKS) {
3647            mRecentTasks.remove(N-1).disposeThumbnail();
3648        }
3649        mRecentTasks.add(0, task);
3650    }
3651
3652    @Override
3653    public void reportActivityFullyDrawn(IBinder token) {
3654        synchronized (this) {
3655            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3656            if (r == null) {
3657                return;
3658            }
3659            r.reportFullyDrawnLocked();
3660        }
3661    }
3662
3663    @Override
3664    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3665        synchronized (this) {
3666            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3667            if (r == null) {
3668                return;
3669            }
3670            final long origId = Binder.clearCallingIdentity();
3671            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3672            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3673                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3674            if (config != null) {
3675                r.frozenBeforeDestroy = true;
3676                if (!updateConfigurationLocked(config, r, false, false)) {
3677                    mStackSupervisor.resumeTopActivitiesLocked();
3678                }
3679            }
3680            Binder.restoreCallingIdentity(origId);
3681        }
3682    }
3683
3684    @Override
3685    public int getRequestedOrientation(IBinder token) {
3686        synchronized (this) {
3687            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3688            if (r == null) {
3689                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3690            }
3691            return mWindowManager.getAppOrientation(r.appToken);
3692        }
3693    }
3694
3695    /**
3696     * This is the internal entry point for handling Activity.finish().
3697     *
3698     * @param token The Binder token referencing the Activity we want to finish.
3699     * @param resultCode Result code, if any, from this Activity.
3700     * @param resultData Result data (Intent), if any, from this Activity.
3701     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3702     *            the root Activity in the task.
3703     *
3704     * @return Returns true if the activity successfully finished, or false if it is still running.
3705     */
3706    @Override
3707    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3708            boolean finishTask) {
3709        // Refuse possible leaked file descriptors
3710        if (resultData != null && resultData.hasFileDescriptors() == true) {
3711            throw new IllegalArgumentException("File descriptors passed in Intent");
3712        }
3713
3714        synchronized(this) {
3715            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3716            if (r == null) {
3717                return true;
3718            }
3719            // Keep track of the root activity of the task before we finish it
3720            TaskRecord tr = r.task;
3721            ActivityRecord rootR = tr.getRootActivity();
3722            // Do not allow task to finish in Lock Task mode.
3723            if (tr == mStackSupervisor.mLockTaskModeTask) {
3724                if (rootR == r) {
3725                    return false;
3726                }
3727            }
3728            if (mController != null) {
3729                // Find the first activity that is not finishing.
3730                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3731                if (next != null) {
3732                    // ask watcher if this is allowed
3733                    boolean resumeOK = true;
3734                    try {
3735                        resumeOK = mController.activityResuming(next.packageName);
3736                    } catch (RemoteException e) {
3737                        mController = null;
3738                        Watchdog.getInstance().setActivityController(null);
3739                    }
3740
3741                    if (!resumeOK) {
3742                        return false;
3743                    }
3744                }
3745            }
3746            final long origId = Binder.clearCallingIdentity();
3747            try {
3748                boolean res;
3749                if (finishTask && r == rootR) {
3750                    // If requested, remove the task that is associated to this activity only if it
3751                    // was the root activity in the task.  The result code and data is ignored because
3752                    // we don't support returning them across task boundaries.
3753                    res = removeTaskByIdLocked(tr.taskId, 0);
3754                } else {
3755                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3756                            resultData, "app-request", true);
3757                }
3758                return res;
3759            } finally {
3760                Binder.restoreCallingIdentity(origId);
3761            }
3762        }
3763    }
3764
3765    @Override
3766    public final void finishHeavyWeightApp() {
3767        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3768                != PackageManager.PERMISSION_GRANTED) {
3769            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3770                    + Binder.getCallingPid()
3771                    + ", uid=" + Binder.getCallingUid()
3772                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3773            Slog.w(TAG, msg);
3774            throw new SecurityException(msg);
3775        }
3776
3777        synchronized(this) {
3778            if (mHeavyWeightProcess == null) {
3779                return;
3780            }
3781
3782            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3783                    mHeavyWeightProcess.activities);
3784            for (int i=0; i<activities.size(); i++) {
3785                ActivityRecord r = activities.get(i);
3786                if (!r.finishing) {
3787                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3788                            null, "finish-heavy", true);
3789                }
3790            }
3791
3792            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3793                    mHeavyWeightProcess.userId, 0));
3794            mHeavyWeightProcess = null;
3795        }
3796    }
3797
3798    @Override
3799    public void crashApplication(int uid, int initialPid, String packageName,
3800            String message) {
3801        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3802                != PackageManager.PERMISSION_GRANTED) {
3803            String msg = "Permission Denial: crashApplication() from pid="
3804                    + Binder.getCallingPid()
3805                    + ", uid=" + Binder.getCallingUid()
3806                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3807            Slog.w(TAG, msg);
3808            throw new SecurityException(msg);
3809        }
3810
3811        synchronized(this) {
3812            ProcessRecord proc = null;
3813
3814            // Figure out which process to kill.  We don't trust that initialPid
3815            // still has any relation to current pids, so must scan through the
3816            // list.
3817            synchronized (mPidsSelfLocked) {
3818                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3819                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3820                    if (p.uid != uid) {
3821                        continue;
3822                    }
3823                    if (p.pid == initialPid) {
3824                        proc = p;
3825                        break;
3826                    }
3827                    if (p.pkgList.containsKey(packageName)) {
3828                        proc = p;
3829                    }
3830                }
3831            }
3832
3833            if (proc == null) {
3834                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3835                        + " initialPid=" + initialPid
3836                        + " packageName=" + packageName);
3837                return;
3838            }
3839
3840            if (proc.thread != null) {
3841                if (proc.pid == Process.myPid()) {
3842                    Log.w(TAG, "crashApplication: trying to crash self!");
3843                    return;
3844                }
3845                long ident = Binder.clearCallingIdentity();
3846                try {
3847                    proc.thread.scheduleCrash(message);
3848                } catch (RemoteException e) {
3849                }
3850                Binder.restoreCallingIdentity(ident);
3851            }
3852        }
3853    }
3854
3855    @Override
3856    public final void finishSubActivity(IBinder token, String resultWho,
3857            int requestCode) {
3858        synchronized(this) {
3859            final long origId = Binder.clearCallingIdentity();
3860            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3861            if (r != null) {
3862                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3863            }
3864            Binder.restoreCallingIdentity(origId);
3865        }
3866    }
3867
3868    @Override
3869    public boolean finishActivityAffinity(IBinder token) {
3870        synchronized(this) {
3871            final long origId = Binder.clearCallingIdentity();
3872            try {
3873                ActivityRecord r = ActivityRecord.isInStackLocked(token);
3874
3875                ActivityRecord rootR = r.task.getRootActivity();
3876                // Do not allow task to finish in Lock Task mode.
3877                if (r.task == mStackSupervisor.mLockTaskModeTask) {
3878                    if (rootR == r) {
3879                        Binder.restoreCallingIdentity(origId);
3880                        return false;
3881                    }
3882                }
3883                boolean res = false;
3884                if (r != null) {
3885                    res = r.task.stack.finishActivityAffinityLocked(r);
3886                }
3887                return res;
3888            } finally {
3889                Binder.restoreCallingIdentity(origId);
3890            }
3891        }
3892    }
3893
3894    @Override
3895    public boolean willActivityBeVisible(IBinder token) {
3896        synchronized(this) {
3897            ActivityStack stack = ActivityRecord.getStackLocked(token);
3898            if (stack != null) {
3899                return stack.willActivityBeVisibleLocked(token);
3900            }
3901            return false;
3902        }
3903    }
3904
3905    @Override
3906    public void overridePendingTransition(IBinder token, String packageName,
3907            int enterAnim, int exitAnim) {
3908        synchronized(this) {
3909            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3910            if (self == null) {
3911                return;
3912            }
3913
3914            final long origId = Binder.clearCallingIdentity();
3915
3916            if (self.state == ActivityState.RESUMED
3917                    || self.state == ActivityState.PAUSING) {
3918                mWindowManager.overridePendingAppTransition(packageName,
3919                        enterAnim, exitAnim, null);
3920            }
3921
3922            Binder.restoreCallingIdentity(origId);
3923        }
3924    }
3925
3926    /**
3927     * Main function for removing an existing process from the activity manager
3928     * as a result of that process going away.  Clears out all connections
3929     * to the process.
3930     */
3931    private final void handleAppDiedLocked(ProcessRecord app,
3932            boolean restarting, boolean allowRestart) {
3933        int pid = app.pid;
3934        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3935        if (!restarting) {
3936            removeLruProcessLocked(app);
3937            if (pid > 0) {
3938                ProcessList.remove(pid);
3939            }
3940        }
3941
3942        if (mProfileProc == app) {
3943            clearProfilerLocked();
3944        }
3945
3946        // Remove this application's activities from active lists.
3947        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3948
3949        app.activities.clear();
3950
3951        if (app.instrumentationClass != null) {
3952            Slog.w(TAG, "Crash of app " + app.processName
3953                  + " running instrumentation " + app.instrumentationClass);
3954            Bundle info = new Bundle();
3955            info.putString("shortMsg", "Process crashed.");
3956            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3957        }
3958
3959        if (!restarting) {
3960            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3961                // If there was nothing to resume, and we are not already
3962                // restarting this process, but there is a visible activity that
3963                // is hosted by the process...  then make sure all visible
3964                // activities are running, taking care of restarting this
3965                // process.
3966                if (hasVisibleActivities) {
3967                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3968                }
3969            }
3970        }
3971    }
3972
3973    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3974        IBinder threadBinder = thread.asBinder();
3975        // Find the application record.
3976        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3977            ProcessRecord rec = mLruProcesses.get(i);
3978            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3979                return i;
3980            }
3981        }
3982        return -1;
3983    }
3984
3985    final ProcessRecord getRecordForAppLocked(
3986            IApplicationThread thread) {
3987        if (thread == null) {
3988            return null;
3989        }
3990
3991        int appIndex = getLRURecordIndexForAppLocked(thread);
3992        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3993    }
3994
3995    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3996        // If there are no longer any background processes running,
3997        // and the app that died was not running instrumentation,
3998        // then tell everyone we are now low on memory.
3999        boolean haveBg = false;
4000        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4001            ProcessRecord rec = mLruProcesses.get(i);
4002            if (rec.thread != null
4003                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4004                haveBg = true;
4005                break;
4006            }
4007        }
4008
4009        if (!haveBg) {
4010            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4011            if (doReport) {
4012                long now = SystemClock.uptimeMillis();
4013                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4014                    doReport = false;
4015                } else {
4016                    mLastMemUsageReportTime = now;
4017                }
4018            }
4019            final ArrayList<ProcessMemInfo> memInfos
4020                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4021            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4022            long now = SystemClock.uptimeMillis();
4023            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4024                ProcessRecord rec = mLruProcesses.get(i);
4025                if (rec == dyingProc || rec.thread == null) {
4026                    continue;
4027                }
4028                if (doReport) {
4029                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4030                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4031                }
4032                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4033                    // The low memory report is overriding any current
4034                    // state for a GC request.  Make sure to do
4035                    // heavy/important/visible/foreground processes first.
4036                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4037                        rec.lastRequestedGc = 0;
4038                    } else {
4039                        rec.lastRequestedGc = rec.lastLowMemory;
4040                    }
4041                    rec.reportLowMemory = true;
4042                    rec.lastLowMemory = now;
4043                    mProcessesToGc.remove(rec);
4044                    addProcessToGcListLocked(rec);
4045                }
4046            }
4047            if (doReport) {
4048                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4049                mHandler.sendMessage(msg);
4050            }
4051            scheduleAppGcsLocked();
4052        }
4053    }
4054
4055    final void appDiedLocked(ProcessRecord app, int pid,
4056            IApplicationThread thread) {
4057
4058        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4059        synchronized (stats) {
4060            stats.noteProcessDiedLocked(app.info.uid, pid);
4061        }
4062
4063        // Clean up already done if the process has been re-started.
4064        if (app.pid == pid && app.thread != null &&
4065                app.thread.asBinder() == thread.asBinder()) {
4066            boolean doLowMem = app.instrumentationClass == null;
4067            boolean doOomAdj = doLowMem;
4068            if (!app.killedByAm) {
4069                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4070                        + ") has died.");
4071                mAllowLowerMemLevel = true;
4072            } else {
4073                // Note that we always want to do oom adj to update our state with the
4074                // new number of procs.
4075                mAllowLowerMemLevel = false;
4076                doLowMem = false;
4077            }
4078            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4079            if (DEBUG_CLEANUP) Slog.v(
4080                TAG, "Dying app: " + app + ", pid: " + pid
4081                + ", thread: " + thread.asBinder());
4082            handleAppDiedLocked(app, false, true);
4083
4084            if (doOomAdj) {
4085                updateOomAdjLocked();
4086            }
4087            if (doLowMem) {
4088                doLowMemReportIfNeededLocked(app);
4089            }
4090        } else if (app.pid != pid) {
4091            // A new process has already been started.
4092            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4093                    + ") has died and restarted (pid " + app.pid + ").");
4094            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4095        } else if (DEBUG_PROCESSES) {
4096            Slog.d(TAG, "Received spurious death notification for thread "
4097                    + thread.asBinder());
4098        }
4099    }
4100
4101    /**
4102     * If a stack trace dump file is configured, dump process stack traces.
4103     * @param clearTraces causes the dump file to be erased prior to the new
4104     *    traces being written, if true; when false, the new traces will be
4105     *    appended to any existing file content.
4106     * @param firstPids of dalvik VM processes to dump stack traces for first
4107     * @param lastPids of dalvik VM processes to dump stack traces for last
4108     * @param nativeProcs optional list of native process names to dump stack crawls
4109     * @return file containing stack traces, or null if no dump file is configured
4110     */
4111    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4112            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4113        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4114        if (tracesPath == null || tracesPath.length() == 0) {
4115            return null;
4116        }
4117
4118        File tracesFile = new File(tracesPath);
4119        try {
4120            File tracesDir = tracesFile.getParentFile();
4121            if (!tracesDir.exists()) {
4122                tracesFile.mkdirs();
4123                if (!SELinux.restorecon(tracesDir)) {
4124                    return null;
4125                }
4126            }
4127            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4128
4129            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4130            tracesFile.createNewFile();
4131            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4132        } catch (IOException e) {
4133            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4134            return null;
4135        }
4136
4137        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4138        return tracesFile;
4139    }
4140
4141    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4142            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4143        // Use a FileObserver to detect when traces finish writing.
4144        // The order of traces is considered important to maintain for legibility.
4145        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4146            @Override
4147            public synchronized void onEvent(int event, String path) { notify(); }
4148        };
4149
4150        try {
4151            observer.startWatching();
4152
4153            // First collect all of the stacks of the most important pids.
4154            if (firstPids != null) {
4155                try {
4156                    int num = firstPids.size();
4157                    for (int i = 0; i < num; i++) {
4158                        synchronized (observer) {
4159                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4160                            observer.wait(200);  // Wait for write-close, give up after 200msec
4161                        }
4162                    }
4163                } catch (InterruptedException e) {
4164                    Log.wtf(TAG, e);
4165                }
4166            }
4167
4168            // Next collect the stacks of the native pids
4169            if (nativeProcs != null) {
4170                int[] pids = Process.getPidsForCommands(nativeProcs);
4171                if (pids != null) {
4172                    for (int pid : pids) {
4173                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4174                    }
4175                }
4176            }
4177
4178            // Lastly, measure CPU usage.
4179            if (processCpuTracker != null) {
4180                processCpuTracker.init();
4181                System.gc();
4182                processCpuTracker.update();
4183                try {
4184                    synchronized (processCpuTracker) {
4185                        processCpuTracker.wait(500); // measure over 1/2 second.
4186                    }
4187                } catch (InterruptedException e) {
4188                }
4189                processCpuTracker.update();
4190
4191                // We'll take the stack crawls of just the top apps using CPU.
4192                final int N = processCpuTracker.countWorkingStats();
4193                int numProcs = 0;
4194                for (int i=0; i<N && numProcs<5; i++) {
4195                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4196                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4197                        numProcs++;
4198                        try {
4199                            synchronized (observer) {
4200                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4201                                observer.wait(200);  // Wait for write-close, give up after 200msec
4202                            }
4203                        } catch (InterruptedException e) {
4204                            Log.wtf(TAG, e);
4205                        }
4206
4207                    }
4208                }
4209            }
4210        } finally {
4211            observer.stopWatching();
4212        }
4213    }
4214
4215    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4216        if (true || IS_USER_BUILD) {
4217            return;
4218        }
4219        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4220        if (tracesPath == null || tracesPath.length() == 0) {
4221            return;
4222        }
4223
4224        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4225        StrictMode.allowThreadDiskWrites();
4226        try {
4227            final File tracesFile = new File(tracesPath);
4228            final File tracesDir = tracesFile.getParentFile();
4229            final File tracesTmp = new File(tracesDir, "__tmp__");
4230            try {
4231                if (!tracesDir.exists()) {
4232                    tracesFile.mkdirs();
4233                    if (!SELinux.restorecon(tracesDir.getPath())) {
4234                        return;
4235                    }
4236                }
4237                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4238
4239                if (tracesFile.exists()) {
4240                    tracesTmp.delete();
4241                    tracesFile.renameTo(tracesTmp);
4242                }
4243                StringBuilder sb = new StringBuilder();
4244                Time tobj = new Time();
4245                tobj.set(System.currentTimeMillis());
4246                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4247                sb.append(": ");
4248                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4249                sb.append(" since ");
4250                sb.append(msg);
4251                FileOutputStream fos = new FileOutputStream(tracesFile);
4252                fos.write(sb.toString().getBytes());
4253                if (app == null) {
4254                    fos.write("\n*** No application process!".getBytes());
4255                }
4256                fos.close();
4257                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4258            } catch (IOException e) {
4259                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4260                return;
4261            }
4262
4263            if (app != null) {
4264                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4265                firstPids.add(app.pid);
4266                dumpStackTraces(tracesPath, firstPids, null, null, null);
4267            }
4268
4269            File lastTracesFile = null;
4270            File curTracesFile = null;
4271            for (int i=9; i>=0; i--) {
4272                String name = String.format(Locale.US, "slow%02d.txt", i);
4273                curTracesFile = new File(tracesDir, name);
4274                if (curTracesFile.exists()) {
4275                    if (lastTracesFile != null) {
4276                        curTracesFile.renameTo(lastTracesFile);
4277                    } else {
4278                        curTracesFile.delete();
4279                    }
4280                }
4281                lastTracesFile = curTracesFile;
4282            }
4283            tracesFile.renameTo(curTracesFile);
4284            if (tracesTmp.exists()) {
4285                tracesTmp.renameTo(tracesFile);
4286            }
4287        } finally {
4288            StrictMode.setThreadPolicy(oldPolicy);
4289        }
4290    }
4291
4292    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4293            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4294        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4295        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4296
4297        if (mController != null) {
4298            try {
4299                // 0 == continue, -1 = kill process immediately
4300                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4301                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
4302            } catch (RemoteException e) {
4303                mController = null;
4304                Watchdog.getInstance().setActivityController(null);
4305            }
4306        }
4307
4308        long anrTime = SystemClock.uptimeMillis();
4309        if (MONITOR_CPU_USAGE) {
4310            updateCpuStatsNow();
4311        }
4312
4313        synchronized (this) {
4314            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4315            if (mShuttingDown) {
4316                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4317                return;
4318            } else if (app.notResponding) {
4319                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4320                return;
4321            } else if (app.crashing) {
4322                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4323                return;
4324            }
4325
4326            // In case we come through here for the same app before completing
4327            // this one, mark as anring now so we will bail out.
4328            app.notResponding = true;
4329
4330            // Log the ANR to the event log.
4331            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4332                    app.processName, app.info.flags, annotation);
4333
4334            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4335            firstPids.add(app.pid);
4336
4337            int parentPid = app.pid;
4338            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4339            if (parentPid != app.pid) firstPids.add(parentPid);
4340
4341            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4342
4343            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4344                ProcessRecord r = mLruProcesses.get(i);
4345                if (r != null && r.thread != null) {
4346                    int pid = r.pid;
4347                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4348                        if (r.persistent) {
4349                            firstPids.add(pid);
4350                        } else {
4351                            lastPids.put(pid, Boolean.TRUE);
4352                        }
4353                    }
4354                }
4355            }
4356        }
4357
4358        // Log the ANR to the main log.
4359        StringBuilder info = new StringBuilder();
4360        info.setLength(0);
4361        info.append("ANR in ").append(app.processName);
4362        if (activity != null && activity.shortComponentName != null) {
4363            info.append(" (").append(activity.shortComponentName).append(")");
4364        }
4365        info.append("\n");
4366        info.append("PID: ").append(app.pid).append("\n");
4367        if (annotation != null) {
4368            info.append("Reason: ").append(annotation).append("\n");
4369        }
4370        if (parent != null && parent != activity) {
4371            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4372        }
4373
4374        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4375
4376        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4377                NATIVE_STACKS_OF_INTEREST);
4378
4379        String cpuInfo = null;
4380        if (MONITOR_CPU_USAGE) {
4381            updateCpuStatsNow();
4382            synchronized (mProcessCpuThread) {
4383                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4384            }
4385            info.append(processCpuTracker.printCurrentLoad());
4386            info.append(cpuInfo);
4387        }
4388
4389        info.append(processCpuTracker.printCurrentState(anrTime));
4390
4391        Slog.e(TAG, info.toString());
4392        if (tracesFile == null) {
4393            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4394            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4395        }
4396
4397        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4398                cpuInfo, tracesFile, null);
4399
4400        if (mController != null) {
4401            try {
4402                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4403                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4404                if (res != 0) {
4405                    if (res < 0 && app.pid != MY_PID) {
4406                        Process.killProcess(app.pid);
4407                    } else {
4408                        synchronized (this) {
4409                            mServices.scheduleServiceTimeoutLocked(app);
4410                        }
4411                    }
4412                    return;
4413                }
4414            } catch (RemoteException e) {
4415                mController = null;
4416                Watchdog.getInstance().setActivityController(null);
4417            }
4418        }
4419
4420        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4421        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4422                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4423
4424        synchronized (this) {
4425            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4426                killUnneededProcessLocked(app, "background ANR");
4427                return;
4428            }
4429
4430            // Set the app's notResponding state, and look up the errorReportReceiver
4431            makeAppNotRespondingLocked(app,
4432                    activity != null ? activity.shortComponentName : null,
4433                    annotation != null ? "ANR " + annotation : "ANR",
4434                    info.toString());
4435
4436            // Bring up the infamous App Not Responding dialog
4437            Message msg = Message.obtain();
4438            HashMap<String, Object> map = new HashMap<String, Object>();
4439            msg.what = SHOW_NOT_RESPONDING_MSG;
4440            msg.obj = map;
4441            msg.arg1 = aboveSystem ? 1 : 0;
4442            map.put("app", app);
4443            if (activity != null) {
4444                map.put("activity", activity);
4445            }
4446
4447            mHandler.sendMessage(msg);
4448        }
4449    }
4450
4451    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4452        if (!mLaunchWarningShown) {
4453            mLaunchWarningShown = true;
4454            mHandler.post(new Runnable() {
4455                @Override
4456                public void run() {
4457                    synchronized (ActivityManagerService.this) {
4458                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4459                        d.show();
4460                        mHandler.postDelayed(new Runnable() {
4461                            @Override
4462                            public void run() {
4463                                synchronized (ActivityManagerService.this) {
4464                                    d.dismiss();
4465                                    mLaunchWarningShown = false;
4466                                }
4467                            }
4468                        }, 4000);
4469                    }
4470                }
4471            });
4472        }
4473    }
4474
4475    @Override
4476    public boolean clearApplicationUserData(final String packageName,
4477            final IPackageDataObserver observer, int userId) {
4478        enforceNotIsolatedCaller("clearApplicationUserData");
4479        int uid = Binder.getCallingUid();
4480        int pid = Binder.getCallingPid();
4481        userId = handleIncomingUser(pid, uid,
4482                userId, false, true, "clearApplicationUserData", null);
4483        long callingId = Binder.clearCallingIdentity();
4484        try {
4485            IPackageManager pm = AppGlobals.getPackageManager();
4486            int pkgUid = -1;
4487            synchronized(this) {
4488                try {
4489                    pkgUid = pm.getPackageUid(packageName, userId);
4490                } catch (RemoteException e) {
4491                }
4492                if (pkgUid == -1) {
4493                    Slog.w(TAG, "Invalid packageName: " + packageName);
4494                    if (observer != null) {
4495                        try {
4496                            observer.onRemoveCompleted(packageName, false);
4497                        } catch (RemoteException e) {
4498                            Slog.i(TAG, "Observer no longer exists.");
4499                        }
4500                    }
4501                    return false;
4502                }
4503                if (uid == pkgUid || checkComponentPermission(
4504                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4505                        pid, uid, -1, true)
4506                        == PackageManager.PERMISSION_GRANTED) {
4507                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4508                } else {
4509                    throw new SecurityException("PID " + pid + " does not have permission "
4510                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4511                                    + " of package " + packageName);
4512                }
4513            }
4514
4515            try {
4516                // Clear application user data
4517                pm.clearApplicationUserData(packageName, observer, userId);
4518
4519                // Remove all permissions granted from/to this package
4520                removeUriPermissionsForPackageLocked(packageName, userId, true);
4521
4522                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4523                        Uri.fromParts("package", packageName, null));
4524                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4525                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4526                        null, null, 0, null, null, null, false, false, userId);
4527            } catch (RemoteException e) {
4528            }
4529        } finally {
4530            Binder.restoreCallingIdentity(callingId);
4531        }
4532        return true;
4533    }
4534
4535    @Override
4536    public void killBackgroundProcesses(final String packageName, int userId) {
4537        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4538                != PackageManager.PERMISSION_GRANTED &&
4539                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4540                        != PackageManager.PERMISSION_GRANTED) {
4541            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4542                    + Binder.getCallingPid()
4543                    + ", uid=" + Binder.getCallingUid()
4544                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4545            Slog.w(TAG, msg);
4546            throw new SecurityException(msg);
4547        }
4548
4549        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4550                userId, true, true, "killBackgroundProcesses", null);
4551        long callingId = Binder.clearCallingIdentity();
4552        try {
4553            IPackageManager pm = AppGlobals.getPackageManager();
4554            synchronized(this) {
4555                int appId = -1;
4556                try {
4557                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4558                } catch (RemoteException e) {
4559                }
4560                if (appId == -1) {
4561                    Slog.w(TAG, "Invalid packageName: " + packageName);
4562                    return;
4563                }
4564                killPackageProcessesLocked(packageName, appId, userId,
4565                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4566            }
4567        } finally {
4568            Binder.restoreCallingIdentity(callingId);
4569        }
4570    }
4571
4572    @Override
4573    public void killAllBackgroundProcesses() {
4574        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4575                != PackageManager.PERMISSION_GRANTED) {
4576            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4577                    + Binder.getCallingPid()
4578                    + ", uid=" + Binder.getCallingUid()
4579                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4580            Slog.w(TAG, msg);
4581            throw new SecurityException(msg);
4582        }
4583
4584        long callingId = Binder.clearCallingIdentity();
4585        try {
4586            synchronized(this) {
4587                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4588                final int NP = mProcessNames.getMap().size();
4589                for (int ip=0; ip<NP; ip++) {
4590                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4591                    final int NA = apps.size();
4592                    for (int ia=0; ia<NA; ia++) {
4593                        ProcessRecord app = apps.valueAt(ia);
4594                        if (app.persistent) {
4595                            // we don't kill persistent processes
4596                            continue;
4597                        }
4598                        if (app.removed) {
4599                            procs.add(app);
4600                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4601                            app.removed = true;
4602                            procs.add(app);
4603                        }
4604                    }
4605                }
4606
4607                int N = procs.size();
4608                for (int i=0; i<N; i++) {
4609                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4610                }
4611                mAllowLowerMemLevel = true;
4612                updateOomAdjLocked();
4613                doLowMemReportIfNeededLocked(null);
4614            }
4615        } finally {
4616            Binder.restoreCallingIdentity(callingId);
4617        }
4618    }
4619
4620    @Override
4621    public void forceStopPackage(final String packageName, int userId) {
4622        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4623                != PackageManager.PERMISSION_GRANTED) {
4624            String msg = "Permission Denial: forceStopPackage() from pid="
4625                    + Binder.getCallingPid()
4626                    + ", uid=" + Binder.getCallingUid()
4627                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4628            Slog.w(TAG, msg);
4629            throw new SecurityException(msg);
4630        }
4631        final int callingPid = Binder.getCallingPid();
4632        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4633                userId, true, true, "forceStopPackage", null);
4634        long callingId = Binder.clearCallingIdentity();
4635        try {
4636            IPackageManager pm = AppGlobals.getPackageManager();
4637            synchronized(this) {
4638                int[] users = userId == UserHandle.USER_ALL
4639                        ? getUsersLocked() : new int[] { userId };
4640                for (int user : users) {
4641                    int pkgUid = -1;
4642                    try {
4643                        pkgUid = pm.getPackageUid(packageName, user);
4644                    } catch (RemoteException e) {
4645                    }
4646                    if (pkgUid == -1) {
4647                        Slog.w(TAG, "Invalid packageName: " + packageName);
4648                        continue;
4649                    }
4650                    try {
4651                        pm.setPackageStoppedState(packageName, true, user);
4652                    } catch (RemoteException e) {
4653                    } catch (IllegalArgumentException e) {
4654                        Slog.w(TAG, "Failed trying to unstop package "
4655                                + packageName + ": " + e);
4656                    }
4657                    if (isUserRunningLocked(user, false)) {
4658                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4659                    }
4660                }
4661            }
4662        } finally {
4663            Binder.restoreCallingIdentity(callingId);
4664        }
4665    }
4666
4667    /*
4668     * The pkg name and app id have to be specified.
4669     */
4670    @Override
4671    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4672        if (pkg == null) {
4673            return;
4674        }
4675        // Make sure the uid is valid.
4676        if (appid < 0) {
4677            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4678            return;
4679        }
4680        int callerUid = Binder.getCallingUid();
4681        // Only the system server can kill an application
4682        if (callerUid == Process.SYSTEM_UID) {
4683            // Post an aysnc message to kill the application
4684            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4685            msg.arg1 = appid;
4686            msg.arg2 = 0;
4687            Bundle bundle = new Bundle();
4688            bundle.putString("pkg", pkg);
4689            bundle.putString("reason", reason);
4690            msg.obj = bundle;
4691            mHandler.sendMessage(msg);
4692        } else {
4693            throw new SecurityException(callerUid + " cannot kill pkg: " +
4694                    pkg);
4695        }
4696    }
4697
4698    @Override
4699    public void closeSystemDialogs(String reason) {
4700        enforceNotIsolatedCaller("closeSystemDialogs");
4701
4702        final int pid = Binder.getCallingPid();
4703        final int uid = Binder.getCallingUid();
4704        final long origId = Binder.clearCallingIdentity();
4705        try {
4706            synchronized (this) {
4707                // Only allow this from foreground processes, so that background
4708                // applications can't abuse it to prevent system UI from being shown.
4709                if (uid >= Process.FIRST_APPLICATION_UID) {
4710                    ProcessRecord proc;
4711                    synchronized (mPidsSelfLocked) {
4712                        proc = mPidsSelfLocked.get(pid);
4713                    }
4714                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4715                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4716                                + " from background process " + proc);
4717                        return;
4718                    }
4719                }
4720                closeSystemDialogsLocked(reason);
4721            }
4722        } finally {
4723            Binder.restoreCallingIdentity(origId);
4724        }
4725    }
4726
4727    void closeSystemDialogsLocked(String reason) {
4728        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4729        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4730                | Intent.FLAG_RECEIVER_FOREGROUND);
4731        if (reason != null) {
4732            intent.putExtra("reason", reason);
4733        }
4734        mWindowManager.closeSystemDialogs(reason);
4735
4736        mStackSupervisor.closeSystemDialogsLocked();
4737
4738        broadcastIntentLocked(null, null, intent, null,
4739                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4740                Process.SYSTEM_UID, UserHandle.USER_ALL);
4741    }
4742
4743    @Override
4744    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4745        enforceNotIsolatedCaller("getProcessMemoryInfo");
4746        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4747        for (int i=pids.length-1; i>=0; i--) {
4748            ProcessRecord proc;
4749            int oomAdj;
4750            synchronized (this) {
4751                synchronized (mPidsSelfLocked) {
4752                    proc = mPidsSelfLocked.get(pids[i]);
4753                    oomAdj = proc != null ? proc.setAdj : 0;
4754                }
4755            }
4756            infos[i] = new Debug.MemoryInfo();
4757            Debug.getMemoryInfo(pids[i], infos[i]);
4758            if (proc != null) {
4759                synchronized (this) {
4760                    if (proc.thread != null && proc.setAdj == oomAdj) {
4761                        // Record this for posterity if the process has been stable.
4762                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4763                                infos[i].getTotalUss(), false, proc.pkgList);
4764                    }
4765                }
4766            }
4767        }
4768        return infos;
4769    }
4770
4771    @Override
4772    public long[] getProcessPss(int[] pids) {
4773        enforceNotIsolatedCaller("getProcessPss");
4774        long[] pss = new long[pids.length];
4775        for (int i=pids.length-1; i>=0; i--) {
4776            ProcessRecord proc;
4777            int oomAdj;
4778            synchronized (this) {
4779                synchronized (mPidsSelfLocked) {
4780                    proc = mPidsSelfLocked.get(pids[i]);
4781                    oomAdj = proc != null ? proc.setAdj : 0;
4782                }
4783            }
4784            long[] tmpUss = new long[1];
4785            pss[i] = Debug.getPss(pids[i], tmpUss);
4786            if (proc != null) {
4787                synchronized (this) {
4788                    if (proc.thread != null && proc.setAdj == oomAdj) {
4789                        // Record this for posterity if the process has been stable.
4790                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4791                    }
4792                }
4793            }
4794        }
4795        return pss;
4796    }
4797
4798    @Override
4799    public void killApplicationProcess(String processName, int uid) {
4800        if (processName == null) {
4801            return;
4802        }
4803
4804        int callerUid = Binder.getCallingUid();
4805        // Only the system server can kill an application
4806        if (callerUid == Process.SYSTEM_UID) {
4807            synchronized (this) {
4808                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4809                if (app != null && app.thread != null) {
4810                    try {
4811                        app.thread.scheduleSuicide();
4812                    } catch (RemoteException e) {
4813                        // If the other end already died, then our work here is done.
4814                    }
4815                } else {
4816                    Slog.w(TAG, "Process/uid not found attempting kill of "
4817                            + processName + " / " + uid);
4818                }
4819            }
4820        } else {
4821            throw new SecurityException(callerUid + " cannot kill app process: " +
4822                    processName);
4823        }
4824    }
4825
4826    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4827        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4828                false, true, false, false, UserHandle.getUserId(uid), reason);
4829        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4830                Uri.fromParts("package", packageName, null));
4831        if (!mProcessesReady) {
4832            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4833                    | Intent.FLAG_RECEIVER_FOREGROUND);
4834        }
4835        intent.putExtra(Intent.EXTRA_UID, uid);
4836        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4837        broadcastIntentLocked(null, null, intent,
4838                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4839                false, false,
4840                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4841    }
4842
4843    private void forceStopUserLocked(int userId, String reason) {
4844        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4845        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4846        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4847                | Intent.FLAG_RECEIVER_FOREGROUND);
4848        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4849        broadcastIntentLocked(null, null, intent,
4850                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4851                false, false,
4852                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4853    }
4854
4855    private final boolean killPackageProcessesLocked(String packageName, int appId,
4856            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4857            boolean doit, boolean evenPersistent, String reason) {
4858        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4859
4860        // Remove all processes this package may have touched: all with the
4861        // same UID (except for the system or root user), and all whose name
4862        // matches the package name.
4863        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4864        final int NP = mProcessNames.getMap().size();
4865        for (int ip=0; ip<NP; ip++) {
4866            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4867            final int NA = apps.size();
4868            for (int ia=0; ia<NA; ia++) {
4869                ProcessRecord app = apps.valueAt(ia);
4870                if (app.persistent && !evenPersistent) {
4871                    // we don't kill persistent processes
4872                    continue;
4873                }
4874                if (app.removed) {
4875                    if (doit) {
4876                        procs.add(app);
4877                    }
4878                    continue;
4879                }
4880
4881                // Skip process if it doesn't meet our oom adj requirement.
4882                if (app.setAdj < minOomAdj) {
4883                    continue;
4884                }
4885
4886                // If no package is specified, we call all processes under the
4887                // give user id.
4888                if (packageName == null) {
4889                    if (app.userId != userId) {
4890                        continue;
4891                    }
4892                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4893                        continue;
4894                    }
4895                // Package has been specified, we want to hit all processes
4896                // that match it.  We need to qualify this by the processes
4897                // that are running under the specified app and user ID.
4898                } else {
4899                    if (UserHandle.getAppId(app.uid) != appId) {
4900                        continue;
4901                    }
4902                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4903                        continue;
4904                    }
4905                    if (!app.pkgList.containsKey(packageName)) {
4906                        continue;
4907                    }
4908                }
4909
4910                // Process has passed all conditions, kill it!
4911                if (!doit) {
4912                    return true;
4913                }
4914                app.removed = true;
4915                procs.add(app);
4916            }
4917        }
4918
4919        int N = procs.size();
4920        for (int i=0; i<N; i++) {
4921            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4922        }
4923        updateOomAdjLocked();
4924        return N > 0;
4925    }
4926
4927    private final boolean forceStopPackageLocked(String name, int appId,
4928            boolean callerWillRestart, boolean purgeCache, boolean doit,
4929            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4930        int i;
4931        int N;
4932
4933        if (userId == UserHandle.USER_ALL && name == null) {
4934            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4935        }
4936
4937        if (appId < 0 && name != null) {
4938            try {
4939                appId = UserHandle.getAppId(
4940                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4941            } catch (RemoteException e) {
4942            }
4943        }
4944
4945        if (doit) {
4946            if (name != null) {
4947                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4948                        + " user=" + userId + ": " + reason);
4949            } else {
4950                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4951            }
4952
4953            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4954            for (int ip=pmap.size()-1; ip>=0; ip--) {
4955                SparseArray<Long> ba = pmap.valueAt(ip);
4956                for (i=ba.size()-1; i>=0; i--) {
4957                    boolean remove = false;
4958                    final int entUid = ba.keyAt(i);
4959                    if (name != null) {
4960                        if (userId == UserHandle.USER_ALL) {
4961                            if (UserHandle.getAppId(entUid) == appId) {
4962                                remove = true;
4963                            }
4964                        } else {
4965                            if (entUid == UserHandle.getUid(userId, appId)) {
4966                                remove = true;
4967                            }
4968                        }
4969                    } else if (UserHandle.getUserId(entUid) == userId) {
4970                        remove = true;
4971                    }
4972                    if (remove) {
4973                        ba.removeAt(i);
4974                    }
4975                }
4976                if (ba.size() == 0) {
4977                    pmap.removeAt(ip);
4978                }
4979            }
4980        }
4981
4982        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4983                -100, callerWillRestart, true, doit, evenPersistent,
4984                name == null ? ("stop user " + userId) : ("stop " + name));
4985
4986        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4987            if (!doit) {
4988                return true;
4989            }
4990            didSomething = true;
4991        }
4992
4993        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4994            if (!doit) {
4995                return true;
4996            }
4997            didSomething = true;
4998        }
4999
5000        if (name == null) {
5001            // Remove all sticky broadcasts from this user.
5002            mStickyBroadcasts.remove(userId);
5003        }
5004
5005        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5006        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5007                userId, providers)) {
5008            if (!doit) {
5009                return true;
5010            }
5011            didSomething = true;
5012        }
5013        N = providers.size();
5014        for (i=0; i<N; i++) {
5015            removeDyingProviderLocked(null, providers.get(i), true);
5016        }
5017
5018        // Remove transient permissions granted from/to this package/user
5019        removeUriPermissionsForPackageLocked(name, userId, false);
5020
5021        if (name == null || uninstalling) {
5022            // Remove pending intents.  For now we only do this when force
5023            // stopping users, because we have some problems when doing this
5024            // for packages -- app widgets are not currently cleaned up for
5025            // such packages, so they can be left with bad pending intents.
5026            if (mIntentSenderRecords.size() > 0) {
5027                Iterator<WeakReference<PendingIntentRecord>> it
5028                        = mIntentSenderRecords.values().iterator();
5029                while (it.hasNext()) {
5030                    WeakReference<PendingIntentRecord> wpir = it.next();
5031                    if (wpir == null) {
5032                        it.remove();
5033                        continue;
5034                    }
5035                    PendingIntentRecord pir = wpir.get();
5036                    if (pir == null) {
5037                        it.remove();
5038                        continue;
5039                    }
5040                    if (name == null) {
5041                        // Stopping user, remove all objects for the user.
5042                        if (pir.key.userId != userId) {
5043                            // Not the same user, skip it.
5044                            continue;
5045                        }
5046                    } else {
5047                        if (UserHandle.getAppId(pir.uid) != appId) {
5048                            // Different app id, skip it.
5049                            continue;
5050                        }
5051                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5052                            // Different user, skip it.
5053                            continue;
5054                        }
5055                        if (!pir.key.packageName.equals(name)) {
5056                            // Different package, skip it.
5057                            continue;
5058                        }
5059                    }
5060                    if (!doit) {
5061                        return true;
5062                    }
5063                    didSomething = true;
5064                    it.remove();
5065                    pir.canceled = true;
5066                    if (pir.key.activity != null) {
5067                        pir.key.activity.pendingResults.remove(pir.ref);
5068                    }
5069                }
5070            }
5071        }
5072
5073        if (doit) {
5074            if (purgeCache && name != null) {
5075                AttributeCache ac = AttributeCache.instance();
5076                if (ac != null) {
5077                    ac.removePackage(name);
5078                }
5079            }
5080            if (mBooted) {
5081                mStackSupervisor.resumeTopActivitiesLocked();
5082                mStackSupervisor.scheduleIdleLocked();
5083            }
5084        }
5085
5086        return didSomething;
5087    }
5088
5089    private final boolean removeProcessLocked(ProcessRecord app,
5090            boolean callerWillRestart, boolean allowRestart, String reason) {
5091        final String name = app.processName;
5092        final int uid = app.uid;
5093        if (DEBUG_PROCESSES) Slog.d(
5094            TAG, "Force removing proc " + app.toShortString() + " (" + name
5095            + "/" + uid + ")");
5096
5097        mProcessNames.remove(name, uid);
5098        mIsolatedProcesses.remove(app.uid);
5099        if (mHeavyWeightProcess == app) {
5100            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5101                    mHeavyWeightProcess.userId, 0));
5102            mHeavyWeightProcess = null;
5103        }
5104        boolean needRestart = false;
5105        if (app.pid > 0 && app.pid != MY_PID) {
5106            int pid = app.pid;
5107            synchronized (mPidsSelfLocked) {
5108                mPidsSelfLocked.remove(pid);
5109                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5110            }
5111            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5112                    app.processName, app.info.uid);
5113            if (app.isolated) {
5114                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5115            }
5116            killUnneededProcessLocked(app, reason);
5117            handleAppDiedLocked(app, true, allowRestart);
5118            removeLruProcessLocked(app);
5119
5120            if (app.persistent && !app.isolated) {
5121                if (!callerWillRestart) {
5122                    addAppLocked(app.info, false, null /* ABI override */);
5123                } else {
5124                    needRestart = true;
5125                }
5126            }
5127        } else {
5128            mRemovedProcesses.add(app);
5129        }
5130
5131        return needRestart;
5132    }
5133
5134    private final void processStartTimedOutLocked(ProcessRecord app) {
5135        final int pid = app.pid;
5136        boolean gone = false;
5137        synchronized (mPidsSelfLocked) {
5138            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5139            if (knownApp != null && knownApp.thread == null) {
5140                mPidsSelfLocked.remove(pid);
5141                gone = true;
5142            }
5143        }
5144
5145        if (gone) {
5146            Slog.w(TAG, "Process " + app + " failed to attach");
5147            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5148                    pid, app.uid, app.processName);
5149            mProcessNames.remove(app.processName, app.uid);
5150            mIsolatedProcesses.remove(app.uid);
5151            if (mHeavyWeightProcess == app) {
5152                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5153                        mHeavyWeightProcess.userId, 0));
5154                mHeavyWeightProcess = null;
5155            }
5156            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5157                    app.processName, app.info.uid);
5158            if (app.isolated) {
5159                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5160            }
5161            // Take care of any launching providers waiting for this process.
5162            checkAppInLaunchingProvidersLocked(app, true);
5163            // Take care of any services that are waiting for the process.
5164            mServices.processStartTimedOutLocked(app);
5165            killUnneededProcessLocked(app, "start timeout");
5166            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5167                Slog.w(TAG, "Unattached app died before backup, skipping");
5168                try {
5169                    IBackupManager bm = IBackupManager.Stub.asInterface(
5170                            ServiceManager.getService(Context.BACKUP_SERVICE));
5171                    bm.agentDisconnected(app.info.packageName);
5172                } catch (RemoteException e) {
5173                    // Can't happen; the backup manager is local
5174                }
5175            }
5176            if (isPendingBroadcastProcessLocked(pid)) {
5177                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5178                skipPendingBroadcastLocked(pid);
5179            }
5180        } else {
5181            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5182        }
5183    }
5184
5185    private final boolean attachApplicationLocked(IApplicationThread thread,
5186            int pid) {
5187
5188        // Find the application record that is being attached...  either via
5189        // the pid if we are running in multiple processes, or just pull the
5190        // next app record if we are emulating process with anonymous threads.
5191        ProcessRecord app;
5192        if (pid != MY_PID && pid >= 0) {
5193            synchronized (mPidsSelfLocked) {
5194                app = mPidsSelfLocked.get(pid);
5195            }
5196        } else {
5197            app = null;
5198        }
5199
5200        if (app == null) {
5201            Slog.w(TAG, "No pending application record for pid " + pid
5202                    + " (IApplicationThread " + thread + "); dropping process");
5203            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5204            if (pid > 0 && pid != MY_PID) {
5205                Process.killProcessQuiet(pid);
5206            } else {
5207                try {
5208                    thread.scheduleExit();
5209                } catch (Exception e) {
5210                    // Ignore exceptions.
5211                }
5212            }
5213            return false;
5214        }
5215
5216        // If this application record is still attached to a previous
5217        // process, clean it up now.
5218        if (app.thread != null) {
5219            handleAppDiedLocked(app, true, true);
5220        }
5221
5222        // Tell the process all about itself.
5223
5224        if (localLOGV) Slog.v(
5225                TAG, "Binding process pid " + pid + " to record " + app);
5226
5227        final String processName = app.processName;
5228        try {
5229            AppDeathRecipient adr = new AppDeathRecipient(
5230                    app, pid, thread);
5231            thread.asBinder().linkToDeath(adr, 0);
5232            app.deathRecipient = adr;
5233        } catch (RemoteException e) {
5234            app.resetPackageList(mProcessStats);
5235            startProcessLocked(app, "link fail", processName, null /* ABI override */);
5236            return false;
5237        }
5238
5239        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5240
5241        app.makeActive(thread, mProcessStats);
5242        app.curAdj = app.setAdj = -100;
5243        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5244        app.forcingToForeground = null;
5245        updateProcessForegroundLocked(app, false, false);
5246        app.hasShownUi = false;
5247        app.debugging = false;
5248        app.cached = false;
5249
5250        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5251
5252        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5253        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5254
5255        if (!normalMode) {
5256            Slog.i(TAG, "Launching preboot mode app: " + app);
5257        }
5258
5259        if (localLOGV) Slog.v(
5260            TAG, "New app record " + app
5261            + " thread=" + thread.asBinder() + " pid=" + pid);
5262        try {
5263            int testMode = IApplicationThread.DEBUG_OFF;
5264            if (mDebugApp != null && mDebugApp.equals(processName)) {
5265                testMode = mWaitForDebugger
5266                    ? IApplicationThread.DEBUG_WAIT
5267                    : IApplicationThread.DEBUG_ON;
5268                app.debugging = true;
5269                if (mDebugTransient) {
5270                    mDebugApp = mOrigDebugApp;
5271                    mWaitForDebugger = mOrigWaitForDebugger;
5272                }
5273            }
5274            String profileFile = app.instrumentationProfileFile;
5275            ParcelFileDescriptor profileFd = null;
5276            boolean profileAutoStop = false;
5277            if (mProfileApp != null && mProfileApp.equals(processName)) {
5278                mProfileProc = app;
5279                profileFile = mProfileFile;
5280                profileFd = mProfileFd;
5281                profileAutoStop = mAutoStopProfiler;
5282            }
5283            boolean enableOpenGlTrace = false;
5284            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5285                enableOpenGlTrace = true;
5286                mOpenGlTraceApp = null;
5287            }
5288
5289            // If the app is being launched for restore or full backup, set it up specially
5290            boolean isRestrictedBackupMode = false;
5291            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5292                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5293                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5294                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5295            }
5296
5297            ensurePackageDexOpt(app.instrumentationInfo != null
5298                    ? app.instrumentationInfo.packageName
5299                    : app.info.packageName);
5300            if (app.instrumentationClass != null) {
5301                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5302            }
5303            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5304                    + processName + " with config " + mConfiguration);
5305            ApplicationInfo appInfo = app.instrumentationInfo != null
5306                    ? app.instrumentationInfo : app.info;
5307            app.compat = compatibilityInfoForPackageLocked(appInfo);
5308            if (profileFd != null) {
5309                profileFd = profileFd.dup();
5310            }
5311            thread.bindApplication(processName, appInfo, providers,
5312                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5313                    app.instrumentationArguments, app.instrumentationWatcher,
5314                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5315                    isRestrictedBackupMode || !normalMode, app.persistent,
5316                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5317                    mCoreSettingsObserver.getCoreSettingsLocked());
5318            updateLruProcessLocked(app, false, null);
5319            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5320        } catch (Exception e) {
5321            // todo: Yikes!  What should we do?  For now we will try to
5322            // start another process, but that could easily get us in
5323            // an infinite loop of restarting processes...
5324            Slog.w(TAG, "Exception thrown during bind!", e);
5325
5326            app.resetPackageList(mProcessStats);
5327            app.unlinkDeathRecipient();
5328            startProcessLocked(app, "bind fail", processName, null /* ABI override */);
5329            return false;
5330        }
5331
5332        // Remove this record from the list of starting applications.
5333        mPersistentStartingProcesses.remove(app);
5334        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5335                "Attach application locked removing on hold: " + app);
5336        mProcessesOnHold.remove(app);
5337
5338        boolean badApp = false;
5339        boolean didSomething = false;
5340
5341        // See if the top visible activity is waiting to run in this process...
5342        if (normalMode) {
5343            try {
5344                if (mStackSupervisor.attachApplicationLocked(app)) {
5345                    didSomething = true;
5346                }
5347            } catch (Exception e) {
5348                badApp = true;
5349            }
5350        }
5351
5352        // Find any services that should be running in this process...
5353        if (!badApp) {
5354            try {
5355                didSomething |= mServices.attachApplicationLocked(app, processName);
5356            } catch (Exception e) {
5357                badApp = true;
5358            }
5359        }
5360
5361        // Check if a next-broadcast receiver is in this process...
5362        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5363            try {
5364                didSomething |= sendPendingBroadcastsLocked(app);
5365            } catch (Exception e) {
5366                // If the app died trying to launch the receiver we declare it 'bad'
5367                badApp = true;
5368            }
5369        }
5370
5371        // Check whether the next backup agent is in this process...
5372        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5373            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5374            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5375            try {
5376                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5377                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5378                        mBackupTarget.backupMode);
5379            } catch (Exception e) {
5380                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5381                e.printStackTrace();
5382            }
5383        }
5384
5385        if (badApp) {
5386            // todo: Also need to kill application to deal with all
5387            // kinds of exceptions.
5388            handleAppDiedLocked(app, false, true);
5389            return false;
5390        }
5391
5392        if (!didSomething) {
5393            updateOomAdjLocked();
5394        }
5395
5396        return true;
5397    }
5398
5399    @Override
5400    public final void attachApplication(IApplicationThread thread) {
5401        synchronized (this) {
5402            int callingPid = Binder.getCallingPid();
5403            final long origId = Binder.clearCallingIdentity();
5404            attachApplicationLocked(thread, callingPid);
5405            Binder.restoreCallingIdentity(origId);
5406        }
5407    }
5408
5409    @Override
5410    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5411        final long origId = Binder.clearCallingIdentity();
5412        synchronized (this) {
5413            ActivityStack stack = ActivityRecord.getStackLocked(token);
5414            if (stack != null) {
5415                ActivityRecord r =
5416                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5417                if (stopProfiling) {
5418                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5419                        try {
5420                            mProfileFd.close();
5421                        } catch (IOException e) {
5422                        }
5423                        clearProfilerLocked();
5424                    }
5425                }
5426            }
5427        }
5428        Binder.restoreCallingIdentity(origId);
5429    }
5430
5431    void enableScreenAfterBoot() {
5432        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5433                SystemClock.uptimeMillis());
5434        mWindowManager.enableScreenAfterBoot();
5435
5436        synchronized (this) {
5437            updateEventDispatchingLocked();
5438        }
5439    }
5440
5441    @Override
5442    public void showBootMessage(final CharSequence msg, final boolean always) {
5443        enforceNotIsolatedCaller("showBootMessage");
5444        mWindowManager.showBootMessage(msg, always);
5445    }
5446
5447    @Override
5448    public void dismissKeyguardOnNextActivity() {
5449        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5450        final long token = Binder.clearCallingIdentity();
5451        try {
5452            synchronized (this) {
5453                if (DEBUG_LOCKSCREEN) logLockScreen("");
5454                if (mLockScreenShown) {
5455                    mLockScreenShown = false;
5456                    comeOutOfSleepIfNeededLocked();
5457                }
5458                mStackSupervisor.setDismissKeyguard(true);
5459            }
5460        } finally {
5461            Binder.restoreCallingIdentity(token);
5462        }
5463    }
5464
5465    final void finishBooting() {
5466        // Register receivers to handle package update events
5467        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5468
5469        synchronized (this) {
5470            // Ensure that any processes we had put on hold are now started
5471            // up.
5472            final int NP = mProcessesOnHold.size();
5473            if (NP > 0) {
5474                ArrayList<ProcessRecord> procs =
5475                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5476                for (int ip=0; ip<NP; ip++) {
5477                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5478                            + procs.get(ip));
5479                    startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */);
5480                }
5481            }
5482
5483            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5484                // Start looking for apps that are abusing wake locks.
5485                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5486                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5487                // Tell anyone interested that we are done booting!
5488                SystemProperties.set("sys.boot_completed", "1");
5489                SystemProperties.set("dev.bootcomplete", "1");
5490                for (int i=0; i<mStartedUsers.size(); i++) {
5491                    UserStartedState uss = mStartedUsers.valueAt(i);
5492                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5493                        uss.mState = UserStartedState.STATE_RUNNING;
5494                        final int userId = mStartedUsers.keyAt(i);
5495                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5496                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5497                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5498                        broadcastIntentLocked(null, null, intent, null,
5499                                new IIntentReceiver.Stub() {
5500                                    @Override
5501                                    public void performReceive(Intent intent, int resultCode,
5502                                            String data, Bundle extras, boolean ordered,
5503                                            boolean sticky, int sendingUser) {
5504                                        synchronized (ActivityManagerService.this) {
5505                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5506                                                    true, false);
5507                                        }
5508                                    }
5509                                },
5510                                0, null, null,
5511                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5512                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5513                                userId);
5514                    }
5515                }
5516                scheduleStartProfilesLocked();
5517            }
5518        }
5519    }
5520
5521    final void ensureBootCompleted() {
5522        boolean booting;
5523        boolean enableScreen;
5524        synchronized (this) {
5525            booting = mBooting;
5526            mBooting = false;
5527            enableScreen = !mBooted;
5528            mBooted = true;
5529        }
5530
5531        if (booting) {
5532            finishBooting();
5533        }
5534
5535        if (enableScreen) {
5536            enableScreenAfterBoot();
5537        }
5538    }
5539
5540    @Override
5541    public final void activityResumed(IBinder token) {
5542        final long origId = Binder.clearCallingIdentity();
5543        synchronized(this) {
5544            ActivityStack stack = ActivityRecord.getStackLocked(token);
5545            if (stack != null) {
5546                ActivityRecord.activityResumedLocked(token);
5547            }
5548        }
5549        Binder.restoreCallingIdentity(origId);
5550    }
5551
5552    @Override
5553    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5554        final long origId = Binder.clearCallingIdentity();
5555        synchronized(this) {
5556            ActivityStack stack = ActivityRecord.getStackLocked(token);
5557            if (stack != null) {
5558                stack.activityPausedLocked(token, false, persistentState);
5559            }
5560        }
5561        Binder.restoreCallingIdentity(origId);
5562    }
5563
5564    @Override
5565    public final void activityStopped(IBinder token, Bundle icicle,
5566            PersistableBundle persistentState, CharSequence description) {
5567        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5568
5569        // Refuse possible leaked file descriptors
5570        if (icicle != null && icicle.hasFileDescriptors()) {
5571            throw new IllegalArgumentException("File descriptors passed in Bundle");
5572        }
5573
5574        final long origId = Binder.clearCallingIdentity();
5575
5576        synchronized (this) {
5577            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5578            if (r != null) {
5579                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5580            }
5581        }
5582
5583        trimApplications();
5584
5585        Binder.restoreCallingIdentity(origId);
5586    }
5587
5588    @Override
5589    public final void activityDestroyed(IBinder token) {
5590        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5591        synchronized (this) {
5592            ActivityStack stack = ActivityRecord.getStackLocked(token);
5593            if (stack != null) {
5594                stack.activityDestroyedLocked(token);
5595            }
5596        }
5597    }
5598
5599    @Override
5600    public String getCallingPackage(IBinder token) {
5601        synchronized (this) {
5602            ActivityRecord r = getCallingRecordLocked(token);
5603            return r != null ? r.info.packageName : null;
5604        }
5605    }
5606
5607    @Override
5608    public ComponentName getCallingActivity(IBinder token) {
5609        synchronized (this) {
5610            ActivityRecord r = getCallingRecordLocked(token);
5611            return r != null ? r.intent.getComponent() : null;
5612        }
5613    }
5614
5615    private ActivityRecord getCallingRecordLocked(IBinder token) {
5616        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5617        if (r == null) {
5618            return null;
5619        }
5620        return r.resultTo;
5621    }
5622
5623    @Override
5624    public ComponentName getActivityClassForToken(IBinder token) {
5625        synchronized(this) {
5626            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5627            if (r == null) {
5628                return null;
5629            }
5630            return r.intent.getComponent();
5631        }
5632    }
5633
5634    @Override
5635    public String getPackageForToken(IBinder token) {
5636        synchronized(this) {
5637            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5638            if (r == null) {
5639                return null;
5640            }
5641            return r.packageName;
5642        }
5643    }
5644
5645    @Override
5646    public IIntentSender getIntentSender(int type,
5647            String packageName, IBinder token, String resultWho,
5648            int requestCode, Intent[] intents, String[] resolvedTypes,
5649            int flags, Bundle options, int userId) {
5650        enforceNotIsolatedCaller("getIntentSender");
5651        // Refuse possible leaked file descriptors
5652        if (intents != null) {
5653            if (intents.length < 1) {
5654                throw new IllegalArgumentException("Intents array length must be >= 1");
5655            }
5656            for (int i=0; i<intents.length; i++) {
5657                Intent intent = intents[i];
5658                if (intent != null) {
5659                    if (intent.hasFileDescriptors()) {
5660                        throw new IllegalArgumentException("File descriptors passed in Intent");
5661                    }
5662                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5663                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5664                        throw new IllegalArgumentException(
5665                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5666                    }
5667                    intents[i] = new Intent(intent);
5668                }
5669            }
5670            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5671                throw new IllegalArgumentException(
5672                        "Intent array length does not match resolvedTypes length");
5673            }
5674        }
5675        if (options != null) {
5676            if (options.hasFileDescriptors()) {
5677                throw new IllegalArgumentException("File descriptors passed in options");
5678            }
5679        }
5680
5681        synchronized(this) {
5682            int callingUid = Binder.getCallingUid();
5683            int origUserId = userId;
5684            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5685                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5686                    "getIntentSender", null);
5687            if (origUserId == UserHandle.USER_CURRENT) {
5688                // We don't want to evaluate this until the pending intent is
5689                // actually executed.  However, we do want to always do the
5690                // security checking for it above.
5691                userId = UserHandle.USER_CURRENT;
5692            }
5693            try {
5694                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5695                    int uid = AppGlobals.getPackageManager()
5696                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5697                    if (!UserHandle.isSameApp(callingUid, uid)) {
5698                        String msg = "Permission Denial: getIntentSender() from pid="
5699                            + Binder.getCallingPid()
5700                            + ", uid=" + Binder.getCallingUid()
5701                            + ", (need uid=" + uid + ")"
5702                            + " is not allowed to send as package " + packageName;
5703                        Slog.w(TAG, msg);
5704                        throw new SecurityException(msg);
5705                    }
5706                }
5707
5708                return getIntentSenderLocked(type, packageName, callingUid, userId,
5709                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5710
5711            } catch (RemoteException e) {
5712                throw new SecurityException(e);
5713            }
5714        }
5715    }
5716
5717    IIntentSender getIntentSenderLocked(int type, String packageName,
5718            int callingUid, int userId, IBinder token, String resultWho,
5719            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5720            Bundle options) {
5721        if (DEBUG_MU)
5722            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5723        ActivityRecord activity = null;
5724        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5725            activity = ActivityRecord.isInStackLocked(token);
5726            if (activity == null) {
5727                return null;
5728            }
5729            if (activity.finishing) {
5730                return null;
5731            }
5732        }
5733
5734        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5735        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5736        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5737        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5738                |PendingIntent.FLAG_UPDATE_CURRENT);
5739
5740        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5741                type, packageName, activity, resultWho,
5742                requestCode, intents, resolvedTypes, flags, options, userId);
5743        WeakReference<PendingIntentRecord> ref;
5744        ref = mIntentSenderRecords.get(key);
5745        PendingIntentRecord rec = ref != null ? ref.get() : null;
5746        if (rec != null) {
5747            if (!cancelCurrent) {
5748                if (updateCurrent) {
5749                    if (rec.key.requestIntent != null) {
5750                        rec.key.requestIntent.replaceExtras(intents != null ?
5751                                intents[intents.length - 1] : null);
5752                    }
5753                    if (intents != null) {
5754                        intents[intents.length-1] = rec.key.requestIntent;
5755                        rec.key.allIntents = intents;
5756                        rec.key.allResolvedTypes = resolvedTypes;
5757                    } else {
5758                        rec.key.allIntents = null;
5759                        rec.key.allResolvedTypes = null;
5760                    }
5761                }
5762                return rec;
5763            }
5764            rec.canceled = true;
5765            mIntentSenderRecords.remove(key);
5766        }
5767        if (noCreate) {
5768            return rec;
5769        }
5770        rec = new PendingIntentRecord(this, key, callingUid);
5771        mIntentSenderRecords.put(key, rec.ref);
5772        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5773            if (activity.pendingResults == null) {
5774                activity.pendingResults
5775                        = new HashSet<WeakReference<PendingIntentRecord>>();
5776            }
5777            activity.pendingResults.add(rec.ref);
5778        }
5779        return rec;
5780    }
5781
5782    @Override
5783    public void cancelIntentSender(IIntentSender sender) {
5784        if (!(sender instanceof PendingIntentRecord)) {
5785            return;
5786        }
5787        synchronized(this) {
5788            PendingIntentRecord rec = (PendingIntentRecord)sender;
5789            try {
5790                int uid = AppGlobals.getPackageManager()
5791                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5792                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5793                    String msg = "Permission Denial: cancelIntentSender() from pid="
5794                        + Binder.getCallingPid()
5795                        + ", uid=" + Binder.getCallingUid()
5796                        + " is not allowed to cancel packges "
5797                        + rec.key.packageName;
5798                    Slog.w(TAG, msg);
5799                    throw new SecurityException(msg);
5800                }
5801            } catch (RemoteException e) {
5802                throw new SecurityException(e);
5803            }
5804            cancelIntentSenderLocked(rec, true);
5805        }
5806    }
5807
5808    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5809        rec.canceled = true;
5810        mIntentSenderRecords.remove(rec.key);
5811        if (cleanActivity && rec.key.activity != null) {
5812            rec.key.activity.pendingResults.remove(rec.ref);
5813        }
5814    }
5815
5816    @Override
5817    public String getPackageForIntentSender(IIntentSender pendingResult) {
5818        if (!(pendingResult instanceof PendingIntentRecord)) {
5819            return null;
5820        }
5821        try {
5822            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5823            return res.key.packageName;
5824        } catch (ClassCastException e) {
5825        }
5826        return null;
5827    }
5828
5829    @Override
5830    public int getUidForIntentSender(IIntentSender sender) {
5831        if (sender instanceof PendingIntentRecord) {
5832            try {
5833                PendingIntentRecord res = (PendingIntentRecord)sender;
5834                return res.uid;
5835            } catch (ClassCastException e) {
5836            }
5837        }
5838        return -1;
5839    }
5840
5841    @Override
5842    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5843        if (!(pendingResult instanceof PendingIntentRecord)) {
5844            return false;
5845        }
5846        try {
5847            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5848            if (res.key.allIntents == null) {
5849                return false;
5850            }
5851            for (int i=0; i<res.key.allIntents.length; i++) {
5852                Intent intent = res.key.allIntents[i];
5853                if (intent.getPackage() != null && intent.getComponent() != null) {
5854                    return false;
5855                }
5856            }
5857            return true;
5858        } catch (ClassCastException e) {
5859        }
5860        return false;
5861    }
5862
5863    @Override
5864    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5865        if (!(pendingResult instanceof PendingIntentRecord)) {
5866            return false;
5867        }
5868        try {
5869            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5870            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5871                return true;
5872            }
5873            return false;
5874        } catch (ClassCastException e) {
5875        }
5876        return false;
5877    }
5878
5879    @Override
5880    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5881        if (!(pendingResult instanceof PendingIntentRecord)) {
5882            return null;
5883        }
5884        try {
5885            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5886            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5887        } catch (ClassCastException e) {
5888        }
5889        return null;
5890    }
5891
5892    @Override
5893    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5894        if (!(pendingResult instanceof PendingIntentRecord)) {
5895            return null;
5896        }
5897        try {
5898            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5899            Intent intent = res.key.requestIntent;
5900            if (intent != null) {
5901                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5902                        || res.lastTagPrefix.equals(prefix))) {
5903                    return res.lastTag;
5904                }
5905                res.lastTagPrefix = prefix;
5906                StringBuilder sb = new StringBuilder(128);
5907                if (prefix != null) {
5908                    sb.append(prefix);
5909                }
5910                if (intent.getAction() != null) {
5911                    sb.append(intent.getAction());
5912                } else if (intent.getComponent() != null) {
5913                    intent.getComponent().appendShortString(sb);
5914                } else {
5915                    sb.append("?");
5916                }
5917                return res.lastTag = sb.toString();
5918            }
5919        } catch (ClassCastException e) {
5920        }
5921        return null;
5922    }
5923
5924    @Override
5925    public void setProcessLimit(int max) {
5926        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5927                "setProcessLimit()");
5928        synchronized (this) {
5929            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5930            mProcessLimitOverride = max;
5931        }
5932        trimApplications();
5933    }
5934
5935    @Override
5936    public int getProcessLimit() {
5937        synchronized (this) {
5938            return mProcessLimitOverride;
5939        }
5940    }
5941
5942    void foregroundTokenDied(ForegroundToken token) {
5943        synchronized (ActivityManagerService.this) {
5944            synchronized (mPidsSelfLocked) {
5945                ForegroundToken cur
5946                    = mForegroundProcesses.get(token.pid);
5947                if (cur != token) {
5948                    return;
5949                }
5950                mForegroundProcesses.remove(token.pid);
5951                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5952                if (pr == null) {
5953                    return;
5954                }
5955                pr.forcingToForeground = null;
5956                updateProcessForegroundLocked(pr, false, false);
5957            }
5958            updateOomAdjLocked();
5959        }
5960    }
5961
5962    @Override
5963    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5964        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5965                "setProcessForeground()");
5966        synchronized(this) {
5967            boolean changed = false;
5968
5969            synchronized (mPidsSelfLocked) {
5970                ProcessRecord pr = mPidsSelfLocked.get(pid);
5971                if (pr == null && isForeground) {
5972                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5973                    return;
5974                }
5975                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5976                if (oldToken != null) {
5977                    oldToken.token.unlinkToDeath(oldToken, 0);
5978                    mForegroundProcesses.remove(pid);
5979                    if (pr != null) {
5980                        pr.forcingToForeground = null;
5981                    }
5982                    changed = true;
5983                }
5984                if (isForeground && token != null) {
5985                    ForegroundToken newToken = new ForegroundToken() {
5986                        @Override
5987                        public void binderDied() {
5988                            foregroundTokenDied(this);
5989                        }
5990                    };
5991                    newToken.pid = pid;
5992                    newToken.token = token;
5993                    try {
5994                        token.linkToDeath(newToken, 0);
5995                        mForegroundProcesses.put(pid, newToken);
5996                        pr.forcingToForeground = token;
5997                        changed = true;
5998                    } catch (RemoteException e) {
5999                        // If the process died while doing this, we will later
6000                        // do the cleanup with the process death link.
6001                    }
6002                }
6003            }
6004
6005            if (changed) {
6006                updateOomAdjLocked();
6007            }
6008        }
6009    }
6010
6011    // =========================================================
6012    // PERMISSIONS
6013    // =========================================================
6014
6015    static class PermissionController extends IPermissionController.Stub {
6016        ActivityManagerService mActivityManagerService;
6017        PermissionController(ActivityManagerService activityManagerService) {
6018            mActivityManagerService = activityManagerService;
6019        }
6020
6021        @Override
6022        public boolean checkPermission(String permission, int pid, int uid) {
6023            return mActivityManagerService.checkPermission(permission, pid,
6024                    uid) == PackageManager.PERMISSION_GRANTED;
6025        }
6026    }
6027
6028    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6029        @Override
6030        public int checkComponentPermission(String permission, int pid, int uid,
6031                int owningUid, boolean exported) {
6032            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6033                    owningUid, exported);
6034        }
6035
6036        @Override
6037        public Object getAMSLock() {
6038            return ActivityManagerService.this;
6039        }
6040    }
6041
6042    /**
6043     * This can be called with or without the global lock held.
6044     */
6045    int checkComponentPermission(String permission, int pid, int uid,
6046            int owningUid, boolean exported) {
6047        // We might be performing an operation on behalf of an indirect binder
6048        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6049        // client identity accordingly before proceeding.
6050        Identity tlsIdentity = sCallerIdentity.get();
6051        if (tlsIdentity != null) {
6052            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6053                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6054            uid = tlsIdentity.uid;
6055            pid = tlsIdentity.pid;
6056        }
6057
6058        if (pid == MY_PID) {
6059            return PackageManager.PERMISSION_GRANTED;
6060        }
6061
6062        return ActivityManager.checkComponentPermission(permission, uid,
6063                owningUid, exported);
6064    }
6065
6066    /**
6067     * As the only public entry point for permissions checking, this method
6068     * can enforce the semantic that requesting a check on a null global
6069     * permission is automatically denied.  (Internally a null permission
6070     * string is used when calling {@link #checkComponentPermission} in cases
6071     * when only uid-based security is needed.)
6072     *
6073     * This can be called with or without the global lock held.
6074     */
6075    @Override
6076    public int checkPermission(String permission, int pid, int uid) {
6077        if (permission == null) {
6078            return PackageManager.PERMISSION_DENIED;
6079        }
6080        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6081    }
6082
6083    /**
6084     * Binder IPC calls go through the public entry point.
6085     * This can be called with or without the global lock held.
6086     */
6087    int checkCallingPermission(String permission) {
6088        return checkPermission(permission,
6089                Binder.getCallingPid(),
6090                UserHandle.getAppId(Binder.getCallingUid()));
6091    }
6092
6093    /**
6094     * This can be called with or without the global lock held.
6095     */
6096    void enforceCallingPermission(String permission, String func) {
6097        if (checkCallingPermission(permission)
6098                == PackageManager.PERMISSION_GRANTED) {
6099            return;
6100        }
6101
6102        String msg = "Permission Denial: " + func + " from pid="
6103                + Binder.getCallingPid()
6104                + ", uid=" + Binder.getCallingUid()
6105                + " requires " + permission;
6106        Slog.w(TAG, msg);
6107        throw new SecurityException(msg);
6108    }
6109
6110    /**
6111     * Determine if UID is holding permissions required to access {@link Uri} in
6112     * the given {@link ProviderInfo}. Final permission checking is always done
6113     * in {@link ContentProvider}.
6114     */
6115    private final boolean checkHoldingPermissionsLocked(
6116            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6117        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6118                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6119        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6120            return false;
6121        }
6122        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6123    }
6124
6125    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6126            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6127        if (pi.applicationInfo.uid == uid) {
6128            return true;
6129        } else if (!pi.exported) {
6130            return false;
6131        }
6132
6133        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6134        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6135        try {
6136            // check if target holds top-level <provider> permissions
6137            if (!readMet && pi.readPermission != null && considerUidPermissions
6138                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6139                readMet = true;
6140            }
6141            if (!writeMet && pi.writePermission != null && considerUidPermissions
6142                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6143                writeMet = true;
6144            }
6145
6146            // track if unprotected read/write is allowed; any denied
6147            // <path-permission> below removes this ability
6148            boolean allowDefaultRead = pi.readPermission == null;
6149            boolean allowDefaultWrite = pi.writePermission == null;
6150
6151            // check if target holds any <path-permission> that match uri
6152            final PathPermission[] pps = pi.pathPermissions;
6153            if (pps != null) {
6154                final String path = grantUri.uri.getPath();
6155                int i = pps.length;
6156                while (i > 0 && (!readMet || !writeMet)) {
6157                    i--;
6158                    PathPermission pp = pps[i];
6159                    if (pp.match(path)) {
6160                        if (!readMet) {
6161                            final String pprperm = pp.getReadPermission();
6162                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6163                                    + pprperm + " for " + pp.getPath()
6164                                    + ": match=" + pp.match(path)
6165                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6166                            if (pprperm != null) {
6167                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6168                                        == PERMISSION_GRANTED) {
6169                                    readMet = true;
6170                                } else {
6171                                    allowDefaultRead = false;
6172                                }
6173                            }
6174                        }
6175                        if (!writeMet) {
6176                            final String ppwperm = pp.getWritePermission();
6177                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6178                                    + ppwperm + " for " + pp.getPath()
6179                                    + ": match=" + pp.match(path)
6180                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6181                            if (ppwperm != null) {
6182                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6183                                        == PERMISSION_GRANTED) {
6184                                    writeMet = true;
6185                                } else {
6186                                    allowDefaultWrite = false;
6187                                }
6188                            }
6189                        }
6190                    }
6191                }
6192            }
6193
6194            // grant unprotected <provider> read/write, if not blocked by
6195            // <path-permission> above
6196            if (allowDefaultRead) readMet = true;
6197            if (allowDefaultWrite) writeMet = true;
6198
6199        } catch (RemoteException e) {
6200            return false;
6201        }
6202
6203        return readMet && writeMet;
6204    }
6205
6206    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6207        ProviderInfo pi = null;
6208        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6209        if (cpr != null) {
6210            pi = cpr.info;
6211        } else {
6212            try {
6213                pi = AppGlobals.getPackageManager().resolveContentProvider(
6214                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6215            } catch (RemoteException ex) {
6216            }
6217        }
6218        return pi;
6219    }
6220
6221    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6222        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6223        if (targetUris != null) {
6224            return targetUris.get(grantUri);
6225        }
6226        return null;
6227    }
6228
6229    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6230            String targetPkg, int targetUid, GrantUri grantUri) {
6231        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6232        if (targetUris == null) {
6233            targetUris = Maps.newArrayMap();
6234            mGrantedUriPermissions.put(targetUid, targetUris);
6235        }
6236
6237        UriPermission perm = targetUris.get(grantUri);
6238        if (perm == null) {
6239            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6240            targetUris.put(grantUri, perm);
6241        }
6242
6243        return perm;
6244    }
6245
6246    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6247            final int modeFlags) {
6248        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6249        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6250                : UriPermission.STRENGTH_OWNED;
6251
6252        // Root gets to do everything.
6253        if (uid == 0) {
6254            return true;
6255        }
6256
6257        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6258        if (perms == null) return false;
6259
6260        // First look for exact match
6261        final UriPermission exactPerm = perms.get(grantUri);
6262        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6263            return true;
6264        }
6265
6266        // No exact match, look for prefixes
6267        final int N = perms.size();
6268        for (int i = 0; i < N; i++) {
6269            final UriPermission perm = perms.valueAt(i);
6270            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6271                    && perm.getStrength(modeFlags) >= minStrength) {
6272                return true;
6273            }
6274        }
6275
6276        return false;
6277    }
6278
6279    @Override
6280    public int checkUriPermission(Uri uri, int pid, int uid,
6281            final int modeFlags, int userId) {
6282        enforceNotIsolatedCaller("checkUriPermission");
6283
6284        // Another redirected-binder-call permissions check as in
6285        // {@link checkComponentPermission}.
6286        Identity tlsIdentity = sCallerIdentity.get();
6287        if (tlsIdentity != null) {
6288            uid = tlsIdentity.uid;
6289            pid = tlsIdentity.pid;
6290        }
6291
6292        // Our own process gets to do everything.
6293        if (pid == MY_PID) {
6294            return PackageManager.PERMISSION_GRANTED;
6295        }
6296        synchronized (this) {
6297            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6298                    ? PackageManager.PERMISSION_GRANTED
6299                    : PackageManager.PERMISSION_DENIED;
6300        }
6301    }
6302
6303    /**
6304     * Check if the targetPkg can be granted permission to access uri by
6305     * the callingUid using the given modeFlags.  Throws a security exception
6306     * if callingUid is not allowed to do this.  Returns the uid of the target
6307     * if the URI permission grant should be performed; returns -1 if it is not
6308     * needed (for example targetPkg already has permission to access the URI).
6309     * If you already know the uid of the target, you can supply it in
6310     * lastTargetUid else set that to -1.
6311     */
6312    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6313            final int modeFlags, int lastTargetUid) {
6314        if (!Intent.isAccessUriMode(modeFlags)) {
6315            return -1;
6316        }
6317
6318        if (targetPkg != null) {
6319            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6320                    "Checking grant " + targetPkg + " permission to " + grantUri);
6321        }
6322
6323        final IPackageManager pm = AppGlobals.getPackageManager();
6324
6325        // If this is not a content: uri, we can't do anything with it.
6326        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6327            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6328                    "Can't grant URI permission for non-content URI: " + grantUri);
6329            return -1;
6330        }
6331
6332        final String authority = grantUri.uri.getAuthority();
6333        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6334        if (pi == null) {
6335            Slog.w(TAG, "No content provider found for permission check: " +
6336                    grantUri.uri.toSafeString());
6337            return -1;
6338        }
6339
6340        int targetUid = lastTargetUid;
6341        if (targetUid < 0 && targetPkg != null) {
6342            try {
6343                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6344                if (targetUid < 0) {
6345                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6346                            "Can't grant URI permission no uid for: " + targetPkg);
6347                    return -1;
6348                }
6349            } catch (RemoteException ex) {
6350                return -1;
6351            }
6352        }
6353
6354        if (targetUid >= 0) {
6355            // First...  does the target actually need this permission?
6356            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6357                // No need to grant the target this permission.
6358                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6359                        "Target " + targetPkg + " already has full permission to " + grantUri);
6360                return -1;
6361            }
6362        } else {
6363            // First...  there is no target package, so can anyone access it?
6364            boolean allowed = pi.exported;
6365            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6366                if (pi.readPermission != null) {
6367                    allowed = false;
6368                }
6369            }
6370            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6371                if (pi.writePermission != null) {
6372                    allowed = false;
6373                }
6374            }
6375            if (allowed) {
6376                return -1;
6377            }
6378        }
6379
6380        /* There is a special cross user grant if:
6381         * - The target is on another user.
6382         * - Apps on the current user can access the uri without any uid permissions.
6383         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6384         * grant uri permissions.
6385         */
6386        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6387                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6388                modeFlags, false /*without considering the uid permissions*/);
6389
6390        // Second...  is the provider allowing granting of URI permissions?
6391        if (!specialCrossUserGrant) {
6392            if (!pi.grantUriPermissions) {
6393                throw new SecurityException("Provider " + pi.packageName
6394                        + "/" + pi.name
6395                        + " does not allow granting of Uri permissions (uri "
6396                        + grantUri + ")");
6397            }
6398            if (pi.uriPermissionPatterns != null) {
6399                final int N = pi.uriPermissionPatterns.length;
6400                boolean allowed = false;
6401                for (int i=0; i<N; i++) {
6402                    if (pi.uriPermissionPatterns[i] != null
6403                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6404                        allowed = true;
6405                        break;
6406                    }
6407                }
6408                if (!allowed) {
6409                    throw new SecurityException("Provider " + pi.packageName
6410                            + "/" + pi.name
6411                            + " does not allow granting of permission to path of Uri "
6412                            + grantUri);
6413                }
6414            }
6415        }
6416
6417        // Third...  does the caller itself have permission to access
6418        // this uri?
6419        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6420            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6421                // Require they hold a strong enough Uri permission
6422                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6423                    throw new SecurityException("Uid " + callingUid
6424                            + " does not have permission to uri " + grantUri);
6425                }
6426            }
6427        }
6428        return targetUid;
6429    }
6430
6431    @Override
6432    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6433            final int modeFlags, int userId) {
6434        enforceNotIsolatedCaller("checkGrantUriPermission");
6435        synchronized(this) {
6436            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6437                    new GrantUri(userId, uri, false), modeFlags, -1);
6438        }
6439    }
6440
6441    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6442            final int modeFlags, UriPermissionOwner owner) {
6443        if (!Intent.isAccessUriMode(modeFlags)) {
6444            return;
6445        }
6446
6447        // So here we are: the caller has the assumed permission
6448        // to the uri, and the target doesn't.  Let's now give this to
6449        // the target.
6450
6451        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6452                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6453
6454        final String authority = grantUri.uri.getAuthority();
6455        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6456        if (pi == null) {
6457            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6458            return;
6459        }
6460
6461        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6462            grantUri.prefix = true;
6463        }
6464        final UriPermission perm = findOrCreateUriPermissionLocked(
6465                pi.packageName, targetPkg, targetUid, grantUri);
6466        perm.grantModes(modeFlags, owner);
6467    }
6468
6469    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6470            final int modeFlags, UriPermissionOwner owner) {
6471        if (targetPkg == null) {
6472            throw new NullPointerException("targetPkg");
6473        }
6474
6475        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6476                -1);
6477        if (targetUid < 0) {
6478            return;
6479        }
6480
6481        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6482                owner);
6483    }
6484
6485    static class NeededUriGrants extends ArrayList<GrantUri> {
6486        final String targetPkg;
6487        final int targetUid;
6488        final int flags;
6489
6490        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6491            this.targetPkg = targetPkg;
6492            this.targetUid = targetUid;
6493            this.flags = flags;
6494        }
6495    }
6496
6497    /**
6498     * Like checkGrantUriPermissionLocked, but takes an Intent.
6499     */
6500    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6501            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6502        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6503                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6504                + " clip=" + (intent != null ? intent.getClipData() : null)
6505                + " from " + intent + "; flags=0x"
6506                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6507
6508        if (targetPkg == null) {
6509            throw new NullPointerException("targetPkg");
6510        }
6511
6512        if (intent == null) {
6513            return null;
6514        }
6515        Uri data = intent.getData();
6516        ClipData clip = intent.getClipData();
6517        if (data == null && clip == null) {
6518            return null;
6519        }
6520        final IPackageManager pm = AppGlobals.getPackageManager();
6521        int targetUid;
6522        if (needed != null) {
6523            targetUid = needed.targetUid;
6524        } else {
6525            try {
6526                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6527            } catch (RemoteException ex) {
6528                return null;
6529            }
6530            if (targetUid < 0) {
6531                if (DEBUG_URI_PERMISSION) {
6532                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6533                            + " on user " + targetUserId);
6534                }
6535                return null;
6536            }
6537        }
6538        if (data != null) {
6539            GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data);
6540            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6541                    targetUid);
6542            if (targetUid > 0) {
6543                if (needed == null) {
6544                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6545                }
6546                needed.add(grantUri);
6547            }
6548        }
6549        if (clip != null) {
6550            for (int i=0; i<clip.getItemCount(); i++) {
6551                Uri uri = clip.getItemAt(i).getUri();
6552                if (uri != null) {
6553                    GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri);
6554                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6555                            targetUid);
6556                    if (targetUid > 0) {
6557                        if (needed == null) {
6558                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6559                        }
6560                        needed.add(grantUri);
6561                    }
6562                } else {
6563                    Intent clipIntent = clip.getItemAt(i).getIntent();
6564                    if (clipIntent != null) {
6565                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6566                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6567                        if (newNeeded != null) {
6568                            needed = newNeeded;
6569                        }
6570                    }
6571                }
6572            }
6573        }
6574
6575        return needed;
6576    }
6577
6578    /**
6579     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6580     */
6581    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6582            UriPermissionOwner owner) {
6583        if (needed != null) {
6584            for (int i=0; i<needed.size(); i++) {
6585                GrantUri grantUri = needed.get(i);
6586                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6587                        grantUri, needed.flags, owner);
6588            }
6589        }
6590    }
6591
6592    void grantUriPermissionFromIntentLocked(int callingUid,
6593            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6594        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6595                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6596        if (needed == null) {
6597            return;
6598        }
6599
6600        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6601    }
6602
6603    @Override
6604    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6605            final int modeFlags, int userId) {
6606        enforceNotIsolatedCaller("grantUriPermission");
6607        GrantUri grantUri = new GrantUri(userId, uri, false);
6608        synchronized(this) {
6609            final ProcessRecord r = getRecordForAppLocked(caller);
6610            if (r == null) {
6611                throw new SecurityException("Unable to find app for caller "
6612                        + caller
6613                        + " when granting permission to uri " + grantUri);
6614            }
6615            if (targetPkg == null) {
6616                throw new IllegalArgumentException("null target");
6617            }
6618            if (grantUri == null) {
6619                throw new IllegalArgumentException("null uri");
6620            }
6621
6622            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6623                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6624                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6625                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6626
6627            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null);
6628        }
6629    }
6630
6631    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6632        if (perm.modeFlags == 0) {
6633            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6634                    perm.targetUid);
6635            if (perms != null) {
6636                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6637                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6638
6639                perms.remove(perm.uri);
6640                if (perms.isEmpty()) {
6641                    mGrantedUriPermissions.remove(perm.targetUid);
6642                }
6643            }
6644        }
6645    }
6646
6647    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6648        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6649
6650        final IPackageManager pm = AppGlobals.getPackageManager();
6651        final String authority = grantUri.uri.getAuthority();
6652        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6653        if (pi == null) {
6654            Slog.w(TAG, "No content provider found for permission revoke: "
6655                    + grantUri.toSafeString());
6656            return;
6657        }
6658
6659        // Does the caller have this permission on the URI?
6660        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6661            // Right now, if you are not the original owner of the permission,
6662            // you are not allowed to revoke it.
6663            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6664                throw new SecurityException("Uid " + callingUid
6665                        + " does not have permission to uri " + grantUri);
6666            //}
6667        }
6668
6669        boolean persistChanged = false;
6670
6671        // Go through all of the permissions and remove any that match.
6672        int N = mGrantedUriPermissions.size();
6673        for (int i = 0; i < N; i++) {
6674            final int targetUid = mGrantedUriPermissions.keyAt(i);
6675            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6676
6677            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6678                final UriPermission perm = it.next();
6679                if (perm.uri.sourceUserId == grantUri.sourceUserId
6680                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6681                    if (DEBUG_URI_PERMISSION)
6682                        Slog.v(TAG,
6683                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6684                    persistChanged |= perm.revokeModes(
6685                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6686                    if (perm.modeFlags == 0) {
6687                        it.remove();
6688                    }
6689                }
6690            }
6691
6692            if (perms.isEmpty()) {
6693                mGrantedUriPermissions.remove(targetUid);
6694                N--;
6695                i--;
6696            }
6697        }
6698
6699        if (persistChanged) {
6700            schedulePersistUriGrants();
6701        }
6702    }
6703
6704    @Override
6705    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6706            int userId) {
6707        enforceNotIsolatedCaller("revokeUriPermission");
6708        synchronized(this) {
6709            final ProcessRecord r = getRecordForAppLocked(caller);
6710            if (r == null) {
6711                throw new SecurityException("Unable to find app for caller "
6712                        + caller
6713                        + " when revoking permission to uri " + uri);
6714            }
6715            if (uri == null) {
6716                Slog.w(TAG, "revokeUriPermission: null uri");
6717                return;
6718            }
6719
6720            if (!Intent.isAccessUriMode(modeFlags)) {
6721                return;
6722            }
6723
6724            final IPackageManager pm = AppGlobals.getPackageManager();
6725            final String authority = uri.getAuthority();
6726            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6727            if (pi == null) {
6728                Slog.w(TAG, "No content provider found for permission revoke: "
6729                        + uri.toSafeString());
6730                return;
6731            }
6732
6733            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6734        }
6735    }
6736
6737    /**
6738     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6739     * given package.
6740     *
6741     * @param packageName Package name to match, or {@code null} to apply to all
6742     *            packages.
6743     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6744     *            to all users.
6745     * @param persistable If persistable grants should be removed.
6746     */
6747    private void removeUriPermissionsForPackageLocked(
6748            String packageName, int userHandle, boolean persistable) {
6749        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6750            throw new IllegalArgumentException("Must narrow by either package or user");
6751        }
6752
6753        boolean persistChanged = false;
6754
6755        int N = mGrantedUriPermissions.size();
6756        for (int i = 0; i < N; i++) {
6757            final int targetUid = mGrantedUriPermissions.keyAt(i);
6758            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6759
6760            // Only inspect grants matching user
6761            if (userHandle == UserHandle.USER_ALL
6762                    || userHandle == UserHandle.getUserId(targetUid)) {
6763                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6764                    final UriPermission perm = it.next();
6765
6766                    // Only inspect grants matching package
6767                    if (packageName == null || perm.sourcePkg.equals(packageName)
6768                            || perm.targetPkg.equals(packageName)) {
6769                        persistChanged |= perm.revokeModes(
6770                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6771
6772                        // Only remove when no modes remain; any persisted grants
6773                        // will keep this alive.
6774                        if (perm.modeFlags == 0) {
6775                            it.remove();
6776                        }
6777                    }
6778                }
6779
6780                if (perms.isEmpty()) {
6781                    mGrantedUriPermissions.remove(targetUid);
6782                    N--;
6783                    i--;
6784                }
6785            }
6786        }
6787
6788        if (persistChanged) {
6789            schedulePersistUriGrants();
6790        }
6791    }
6792
6793    @Override
6794    public IBinder newUriPermissionOwner(String name) {
6795        enforceNotIsolatedCaller("newUriPermissionOwner");
6796        synchronized(this) {
6797            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6798            return owner.getExternalTokenLocked();
6799        }
6800    }
6801
6802    @Override
6803    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6804            final int modeFlags, int userId) {
6805        synchronized(this) {
6806            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6807            if (owner == null) {
6808                throw new IllegalArgumentException("Unknown owner: " + token);
6809            }
6810            if (fromUid != Binder.getCallingUid()) {
6811                if (Binder.getCallingUid() != Process.myUid()) {
6812                    // Only system code can grant URI permissions on behalf
6813                    // of other users.
6814                    throw new SecurityException("nice try");
6815                }
6816            }
6817            if (targetPkg == null) {
6818                throw new IllegalArgumentException("null target");
6819            }
6820            if (uri == null) {
6821                throw new IllegalArgumentException("null uri");
6822            }
6823
6824            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false),
6825                    modeFlags, owner);
6826        }
6827    }
6828
6829    @Override
6830    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6831        synchronized(this) {
6832            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6833            if (owner == null) {
6834                throw new IllegalArgumentException("Unknown owner: " + token);
6835            }
6836
6837            if (uri == null) {
6838                owner.removeUriPermissionsLocked(mode);
6839            } else {
6840                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
6841            }
6842        }
6843    }
6844
6845    private void schedulePersistUriGrants() {
6846        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6847            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6848                    10 * DateUtils.SECOND_IN_MILLIS);
6849        }
6850    }
6851
6852    private void writeGrantedUriPermissions() {
6853        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6854
6855        // Snapshot permissions so we can persist without lock
6856        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6857        synchronized (this) {
6858            final int size = mGrantedUriPermissions.size();
6859            for (int i = 0; i < size; i++) {
6860                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6861                for (UriPermission perm : perms.values()) {
6862                    if (perm.persistedModeFlags != 0) {
6863                        persist.add(perm.snapshot());
6864                    }
6865                }
6866            }
6867        }
6868
6869        FileOutputStream fos = null;
6870        try {
6871            fos = mGrantFile.startWrite();
6872
6873            XmlSerializer out = new FastXmlSerializer();
6874            out.setOutput(fos, "utf-8");
6875            out.startDocument(null, true);
6876            out.startTag(null, TAG_URI_GRANTS);
6877            for (UriPermission.Snapshot perm : persist) {
6878                out.startTag(null, TAG_URI_GRANT);
6879                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
6880                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
6881                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6882                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6883                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6884                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6885                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6886                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6887                out.endTag(null, TAG_URI_GRANT);
6888            }
6889            out.endTag(null, TAG_URI_GRANTS);
6890            out.endDocument();
6891
6892            mGrantFile.finishWrite(fos);
6893        } catch (IOException e) {
6894            if (fos != null) {
6895                mGrantFile.failWrite(fos);
6896            }
6897        }
6898    }
6899
6900    private void readGrantedUriPermissionsLocked() {
6901        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6902
6903        final long now = System.currentTimeMillis();
6904
6905        FileInputStream fis = null;
6906        try {
6907            fis = mGrantFile.openRead();
6908            final XmlPullParser in = Xml.newPullParser();
6909            in.setInput(fis, null);
6910
6911            int type;
6912            while ((type = in.next()) != END_DOCUMENT) {
6913                final String tag = in.getName();
6914                if (type == START_TAG) {
6915                    if (TAG_URI_GRANT.equals(tag)) {
6916                        final int sourceUserId;
6917                        final int targetUserId;
6918                        final int userHandle = readIntAttribute(in,
6919                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
6920                        if (userHandle != UserHandle.USER_NULL) {
6921                            // For backwards compatibility.
6922                            sourceUserId = userHandle;
6923                            targetUserId = userHandle;
6924                        } else {
6925                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
6926                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
6927                        }
6928                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6929                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6930                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6931                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
6932                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6933                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6934
6935                        // Sanity check that provider still belongs to source package
6936                        final ProviderInfo pi = getProviderInfoLocked(
6937                                uri.getAuthority(), sourceUserId);
6938                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6939                            int targetUid = -1;
6940                            try {
6941                                targetUid = AppGlobals.getPackageManager()
6942                                        .getPackageUid(targetPkg, targetUserId);
6943                            } catch (RemoteException e) {
6944                            }
6945                            if (targetUid != -1) {
6946                                final UriPermission perm = findOrCreateUriPermissionLocked(
6947                                        sourcePkg, targetPkg, targetUid,
6948                                        new GrantUri(sourceUserId, uri, prefix));
6949                                perm.initPersistedModes(modeFlags, createdTime);
6950                            }
6951                        } else {
6952                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6953                                    + " but instead found " + pi);
6954                        }
6955                    }
6956                }
6957            }
6958        } catch (FileNotFoundException e) {
6959            // Missing grants is okay
6960        } catch (IOException e) {
6961            Log.wtf(TAG, "Failed reading Uri grants", e);
6962        } catch (XmlPullParserException e) {
6963            Log.wtf(TAG, "Failed reading Uri grants", e);
6964        } finally {
6965            IoUtils.closeQuietly(fis);
6966        }
6967    }
6968
6969    @Override
6970    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6971        enforceNotIsolatedCaller("takePersistableUriPermission");
6972
6973        Preconditions.checkFlagsArgument(modeFlags,
6974                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6975
6976        synchronized (this) {
6977            final int callingUid = Binder.getCallingUid();
6978            boolean persistChanged = false;
6979            GrantUri grantUri = new GrantUri(userId, uri, false);
6980
6981            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6982                    new GrantUri(userId, uri, false));
6983            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6984                    new GrantUri(userId, uri, true));
6985
6986            final boolean exactValid = (exactPerm != null)
6987                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
6988            final boolean prefixValid = (prefixPerm != null)
6989                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
6990
6991            if (!(exactValid || prefixValid)) {
6992                throw new SecurityException("No persistable permission grants found for UID "
6993                        + callingUid + " and Uri " + grantUri.toSafeString());
6994            }
6995
6996            if (exactValid) {
6997                persistChanged |= exactPerm.takePersistableModes(modeFlags);
6998            }
6999            if (prefixValid) {
7000                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7001            }
7002
7003            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7004
7005            if (persistChanged) {
7006                schedulePersistUriGrants();
7007            }
7008        }
7009    }
7010
7011    @Override
7012    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7013        enforceNotIsolatedCaller("releasePersistableUriPermission");
7014
7015        Preconditions.checkFlagsArgument(modeFlags,
7016                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7017
7018        synchronized (this) {
7019            final int callingUid = Binder.getCallingUid();
7020            boolean persistChanged = false;
7021
7022            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7023                    new GrantUri(userId, uri, false));
7024            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7025                    new GrantUri(userId, uri, true));
7026            if (exactPerm == null && prefixPerm == null) {
7027                throw new SecurityException("No permission grants found for UID " + callingUid
7028                        + " and Uri " + uri.toSafeString());
7029            }
7030
7031            if (exactPerm != null) {
7032                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7033                removeUriPermissionIfNeededLocked(exactPerm);
7034            }
7035            if (prefixPerm != null) {
7036                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7037                removeUriPermissionIfNeededLocked(prefixPerm);
7038            }
7039
7040            if (persistChanged) {
7041                schedulePersistUriGrants();
7042            }
7043        }
7044    }
7045
7046    /**
7047     * Prune any older {@link UriPermission} for the given UID until outstanding
7048     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7049     *
7050     * @return if any mutations occured that require persisting.
7051     */
7052    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7053        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7054        if (perms == null) return false;
7055        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7056
7057        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7058        for (UriPermission perm : perms.values()) {
7059            if (perm.persistedModeFlags != 0) {
7060                persisted.add(perm);
7061            }
7062        }
7063
7064        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7065        if (trimCount <= 0) return false;
7066
7067        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7068        for (int i = 0; i < trimCount; i++) {
7069            final UriPermission perm = persisted.get(i);
7070
7071            if (DEBUG_URI_PERMISSION) {
7072                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7073            }
7074
7075            perm.releasePersistableModes(~0);
7076            removeUriPermissionIfNeededLocked(perm);
7077        }
7078
7079        return true;
7080    }
7081
7082    @Override
7083    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7084            String packageName, boolean incoming) {
7085        enforceNotIsolatedCaller("getPersistedUriPermissions");
7086        Preconditions.checkNotNull(packageName, "packageName");
7087
7088        final int callingUid = Binder.getCallingUid();
7089        final IPackageManager pm = AppGlobals.getPackageManager();
7090        try {
7091            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7092            if (packageUid != callingUid) {
7093                throw new SecurityException(
7094                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7095            }
7096        } catch (RemoteException e) {
7097            throw new SecurityException("Failed to verify package name ownership");
7098        }
7099
7100        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7101        synchronized (this) {
7102            if (incoming) {
7103                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7104                        callingUid);
7105                if (perms == null) {
7106                    Slog.w(TAG, "No permission grants found for " + packageName);
7107                } else {
7108                    for (UriPermission perm : perms.values()) {
7109                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7110                            result.add(perm.buildPersistedPublicApiObject());
7111                        }
7112                    }
7113                }
7114            } else {
7115                final int size = mGrantedUriPermissions.size();
7116                for (int i = 0; i < size; i++) {
7117                    final ArrayMap<GrantUri, UriPermission> perms =
7118                            mGrantedUriPermissions.valueAt(i);
7119                    for (UriPermission perm : perms.values()) {
7120                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7121                            result.add(perm.buildPersistedPublicApiObject());
7122                        }
7123                    }
7124                }
7125            }
7126        }
7127        return new ParceledListSlice<android.content.UriPermission>(result);
7128    }
7129
7130    @Override
7131    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7132        synchronized (this) {
7133            ProcessRecord app =
7134                who != null ? getRecordForAppLocked(who) : null;
7135            if (app == null) return;
7136
7137            Message msg = Message.obtain();
7138            msg.what = WAIT_FOR_DEBUGGER_MSG;
7139            msg.obj = app;
7140            msg.arg1 = waiting ? 1 : 0;
7141            mHandler.sendMessage(msg);
7142        }
7143    }
7144
7145    @Override
7146    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7147        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7148        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7149        outInfo.availMem = Process.getFreeMemory();
7150        outInfo.totalMem = Process.getTotalMemory();
7151        outInfo.threshold = homeAppMem;
7152        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7153        outInfo.hiddenAppThreshold = cachedAppMem;
7154        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7155                ProcessList.SERVICE_ADJ);
7156        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7157                ProcessList.VISIBLE_APP_ADJ);
7158        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7159                ProcessList.FOREGROUND_APP_ADJ);
7160    }
7161
7162    // =========================================================
7163    // TASK MANAGEMENT
7164    // =========================================================
7165
7166    @Override
7167    public List<IAppTask> getAppTasks() {
7168        int callingUid = Binder.getCallingUid();
7169        long ident = Binder.clearCallingIdentity();
7170        synchronized(this) {
7171            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7172            try {
7173                if (localLOGV) Slog.v(TAG, "getAppTasks");
7174
7175                final int N = mRecentTasks.size();
7176                for (int i = 0; i < N; i++) {
7177                    TaskRecord tr = mRecentTasks.get(i);
7178                    // Skip tasks that are not created by the caller
7179                    if (tr.creatorUid == callingUid) {
7180                        ActivityManager.RecentTaskInfo taskInfo =
7181                                createRecentTaskInfoFromTaskRecord(tr);
7182                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7183                        list.add(taskImpl);
7184                    }
7185                }
7186            } finally {
7187                Binder.restoreCallingIdentity(ident);
7188            }
7189            return list;
7190        }
7191    }
7192
7193    @Override
7194    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7195        final int callingUid = Binder.getCallingUid();
7196        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7197
7198        synchronized(this) {
7199            if (localLOGV) Slog.v(
7200                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7201
7202            final boolean allowed = checkCallingPermission(
7203                    android.Manifest.permission.GET_TASKS)
7204                    == PackageManager.PERMISSION_GRANTED;
7205            if (!allowed) {
7206                Slog.w(TAG, "getTasks: caller " + callingUid
7207                        + " does not hold GET_TASKS; limiting output");
7208            }
7209
7210            // TODO: Improve with MRU list from all ActivityStacks.
7211            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7212        }
7213
7214        return list;
7215    }
7216
7217    TaskRecord getMostRecentTask() {
7218        return mRecentTasks.get(0);
7219    }
7220
7221    /**
7222     * Creates a new RecentTaskInfo from a TaskRecord.
7223     */
7224    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7225        // Update the task description to reflect any changes in the task stack
7226        tr.updateTaskDescription();
7227
7228        // Compose the recent task info
7229        ActivityManager.RecentTaskInfo rti
7230                = new ActivityManager.RecentTaskInfo();
7231        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7232        rti.persistentId = tr.taskId;
7233        rti.baseIntent = new Intent(tr.getBaseIntent());
7234        rti.origActivity = tr.origActivity;
7235        rti.description = tr.lastDescription;
7236        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7237        rti.userId = tr.userId;
7238        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7239        return rti;
7240    }
7241
7242    @Override
7243    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
7244            int flags, int userId) {
7245        final int callingUid = Binder.getCallingUid();
7246        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7247                false, true, "getRecentTasks", null);
7248
7249        synchronized (this) {
7250            final boolean allowed = checkCallingPermission(
7251                    android.Manifest.permission.GET_TASKS)
7252                    == PackageManager.PERMISSION_GRANTED;
7253            if (!allowed) {
7254                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7255                        + " does not hold GET_TASKS; limiting output");
7256            }
7257            final boolean detailed = checkCallingPermission(
7258                    android.Manifest.permission.GET_DETAILED_TASKS)
7259                    == PackageManager.PERMISSION_GRANTED;
7260
7261            IPackageManager pm = AppGlobals.getPackageManager();
7262
7263            final int N = mRecentTasks.size();
7264            ArrayList<ActivityManager.RecentTaskInfo> res
7265                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7266                            maxNum < N ? maxNum : N);
7267
7268            final Set<Integer> includedUsers;
7269            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
7270                includedUsers = getProfileIdsLocked(userId);
7271            } else {
7272                includedUsers = new HashSet<Integer>();
7273            }
7274            includedUsers.add(Integer.valueOf(userId));
7275            for (int i=0; i<N && maxNum > 0; i++) {
7276                TaskRecord tr = mRecentTasks.get(i);
7277                // Only add calling user or related users recent tasks
7278                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7279
7280                // Return the entry if desired by the caller.  We always return
7281                // the first entry, because callers always expect this to be the
7282                // foreground app.  We may filter others if the caller has
7283                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7284                // we should exclude the entry.
7285
7286                if (i == 0
7287                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
7288                        || (tr.intent == null)
7289                        || ((tr.intent.getFlags()
7290                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
7291                    if (!allowed) {
7292                        // If the caller doesn't have the GET_TASKS permission, then only
7293                        // allow them to see a small subset of tasks -- their own and home.
7294                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7295                            continue;
7296                        }
7297                    }
7298                    if (tr.intent != null &&
7299                            (tr.intent.getFlags() & Intent.FLAG_ACTIVITY_AUTO_REMOVE_FROM_RECENTS)
7300                            != 0 && tr.getTopActivity() == null) {
7301                        // Don't include auto remove tasks that are finished or finishing.
7302                        continue;
7303                    }
7304
7305                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7306                    if (!detailed) {
7307                        rti.baseIntent.replaceExtras((Bundle)null);
7308                    }
7309
7310                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7311                        // Check whether this activity is currently available.
7312                        try {
7313                            if (rti.origActivity != null) {
7314                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7315                                        == null) {
7316                                    continue;
7317                                }
7318                            } else if (rti.baseIntent != null) {
7319                                if (pm.queryIntentActivities(rti.baseIntent,
7320                                        null, 0, userId) == null) {
7321                                    continue;
7322                                }
7323                            }
7324                        } catch (RemoteException e) {
7325                            // Will never happen.
7326                        }
7327                    }
7328
7329                    res.add(rti);
7330                    maxNum--;
7331                }
7332            }
7333            return res;
7334        }
7335    }
7336
7337    private TaskRecord recentTaskForIdLocked(int id) {
7338        final int N = mRecentTasks.size();
7339            for (int i=0; i<N; i++) {
7340                TaskRecord tr = mRecentTasks.get(i);
7341                if (tr.taskId == id) {
7342                    return tr;
7343                }
7344            }
7345            return null;
7346    }
7347
7348    @Override
7349    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
7350        synchronized (this) {
7351            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7352                    "getTaskThumbnails()");
7353            TaskRecord tr = recentTaskForIdLocked(id);
7354            if (tr != null) {
7355                return tr.getTaskThumbnailsLocked();
7356            }
7357        }
7358        return null;
7359    }
7360
7361    @Override
7362    public Bitmap getTaskTopThumbnail(int id) {
7363        synchronized (this) {
7364            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7365                    "getTaskTopThumbnail()");
7366            TaskRecord tr = recentTaskForIdLocked(id);
7367            if (tr != null) {
7368                return tr.getTaskTopThumbnailLocked();
7369            }
7370        }
7371        return null;
7372    }
7373
7374    @Override
7375    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7376        synchronized (this) {
7377            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7378            if (r != null) {
7379                r.taskDescription = td;
7380                r.task.updateTaskDescription();
7381            }
7382        }
7383    }
7384
7385    @Override
7386    public boolean removeSubTask(int taskId, int subTaskIndex) {
7387        synchronized (this) {
7388            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7389                    "removeSubTask()");
7390            long ident = Binder.clearCallingIdentity();
7391            try {
7392                TaskRecord tr = recentTaskForIdLocked(taskId);
7393                if (tr != null) {
7394                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
7395                }
7396                return false;
7397            } finally {
7398                Binder.restoreCallingIdentity(ident);
7399            }
7400        }
7401    }
7402
7403    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7404        if (!pr.killedByAm) {
7405            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7406            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7407                    pr.processName, pr.setAdj, reason);
7408            pr.killedByAm = true;
7409            Process.killProcessQuiet(pr.pid);
7410        }
7411    }
7412
7413    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7414        tr.disposeThumbnail();
7415        mRecentTasks.remove(tr);
7416        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7417        Intent baseIntent = new Intent(
7418                tr.intent != null ? tr.intent : tr.affinityIntent);
7419        ComponentName component = baseIntent.getComponent();
7420        if (component == null) {
7421            Slog.w(TAG, "Now component for base intent of task: " + tr);
7422            return;
7423        }
7424
7425        // Find any running services associated with this app.
7426        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7427
7428        if (killProcesses) {
7429            // Find any running processes associated with this app.
7430            final String pkg = component.getPackageName();
7431            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7432            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7433            for (int i=0; i<pmap.size(); i++) {
7434                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7435                for (int j=0; j<uids.size(); j++) {
7436                    ProcessRecord proc = uids.valueAt(j);
7437                    if (proc.userId != tr.userId) {
7438                        continue;
7439                    }
7440                    if (!proc.pkgList.containsKey(pkg)) {
7441                        continue;
7442                    }
7443                    procs.add(proc);
7444                }
7445            }
7446
7447            // Kill the running processes.
7448            for (int i=0; i<procs.size(); i++) {
7449                ProcessRecord pr = procs.get(i);
7450                if (pr == mHomeProcess) {
7451                    // Don't kill the home process along with tasks from the same package.
7452                    continue;
7453                }
7454                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7455                    killUnneededProcessLocked(pr, "remove task");
7456                } else {
7457                    pr.waitingToKill = "remove task";
7458                }
7459            }
7460        }
7461    }
7462
7463    /**
7464     * Removes the task with the specified task id.
7465     *
7466     * @param taskId Identifier of the task to be removed.
7467     * @param flags Additional operational flags.  May be 0 or
7468     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7469     * @return Returns true if the given task was found and removed.
7470     */
7471    private boolean removeTaskByIdLocked(int taskId, int flags) {
7472        TaskRecord tr = recentTaskForIdLocked(taskId);
7473        if (tr != null) {
7474            tr.removeTaskActivitiesLocked(-1, false);
7475            cleanUpRemovedTaskLocked(tr, flags);
7476            if (tr.isPersistable) {
7477                notifyTaskPersisterLocked(tr, true);
7478            }
7479            return true;
7480        }
7481        return false;
7482    }
7483
7484    @Override
7485    public boolean removeTask(int taskId, int flags) {
7486        synchronized (this) {
7487            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7488                    "removeTask()");
7489            long ident = Binder.clearCallingIdentity();
7490            try {
7491                return removeTaskByIdLocked(taskId, flags);
7492            } finally {
7493                Binder.restoreCallingIdentity(ident);
7494            }
7495        }
7496    }
7497
7498    /**
7499     * TODO: Add mController hook
7500     */
7501    @Override
7502    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7503        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7504                "moveTaskToFront()");
7505
7506        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7507        synchronized(this) {
7508            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7509                    Binder.getCallingUid(), "Task to front")) {
7510                ActivityOptions.abort(options);
7511                return;
7512            }
7513            final long origId = Binder.clearCallingIdentity();
7514            try {
7515                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7516                if (task == null) {
7517                    return;
7518                }
7519                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7520                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7521                    return;
7522                }
7523                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7524            } finally {
7525                Binder.restoreCallingIdentity(origId);
7526            }
7527            ActivityOptions.abort(options);
7528        }
7529    }
7530
7531    @Override
7532    public void moveTaskToBack(int taskId) {
7533        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7534                "moveTaskToBack()");
7535
7536        synchronized(this) {
7537            TaskRecord tr = recentTaskForIdLocked(taskId);
7538            if (tr != null) {
7539                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7540                ActivityStack stack = tr.stack;
7541                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7542                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7543                            Binder.getCallingUid(), "Task to back")) {
7544                        return;
7545                    }
7546                }
7547                final long origId = Binder.clearCallingIdentity();
7548                try {
7549                    stack.moveTaskToBackLocked(taskId, null);
7550                } finally {
7551                    Binder.restoreCallingIdentity(origId);
7552                }
7553            }
7554        }
7555    }
7556
7557    /**
7558     * Moves an activity, and all of the other activities within the same task, to the bottom
7559     * of the history stack.  The activity's order within the task is unchanged.
7560     *
7561     * @param token A reference to the activity we wish to move
7562     * @param nonRoot If false then this only works if the activity is the root
7563     *                of a task; if true it will work for any activity in a task.
7564     * @return Returns true if the move completed, false if not.
7565     */
7566    @Override
7567    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7568        enforceNotIsolatedCaller("moveActivityTaskToBack");
7569        synchronized(this) {
7570            final long origId = Binder.clearCallingIdentity();
7571            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7572            if (taskId >= 0) {
7573                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7574            }
7575            Binder.restoreCallingIdentity(origId);
7576        }
7577        return false;
7578    }
7579
7580    @Override
7581    public void moveTaskBackwards(int task) {
7582        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7583                "moveTaskBackwards()");
7584
7585        synchronized(this) {
7586            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7587                    Binder.getCallingUid(), "Task backwards")) {
7588                return;
7589            }
7590            final long origId = Binder.clearCallingIdentity();
7591            moveTaskBackwardsLocked(task);
7592            Binder.restoreCallingIdentity(origId);
7593        }
7594    }
7595
7596    private final void moveTaskBackwardsLocked(int task) {
7597        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7598    }
7599
7600    @Override
7601    public IBinder getHomeActivityToken() throws RemoteException {
7602        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7603                "getHomeActivityToken()");
7604        synchronized (this) {
7605            return mStackSupervisor.getHomeActivityToken();
7606        }
7607    }
7608
7609    @Override
7610    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7611            IActivityContainerCallback callback) throws RemoteException {
7612        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7613                "createActivityContainer()");
7614        synchronized (this) {
7615            if (parentActivityToken == null) {
7616                throw new IllegalArgumentException("parent token must not be null");
7617            }
7618            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7619            if (r == null) {
7620                return null;
7621            }
7622            if (callback == null) {
7623                throw new IllegalArgumentException("callback must not be null");
7624            }
7625            return mStackSupervisor.createActivityContainer(r, callback);
7626        }
7627    }
7628
7629    @Override
7630    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7631        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7632                "deleteActivityContainer()");
7633        synchronized (this) {
7634            mStackSupervisor.deleteActivityContainer(container);
7635        }
7636    }
7637
7638    @Override
7639    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7640            throws RemoteException {
7641        synchronized (this) {
7642            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7643            if (stack != null) {
7644                return stack.mActivityContainer;
7645            }
7646            return null;
7647        }
7648    }
7649
7650    @Override
7651    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7652        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7653                "moveTaskToStack()");
7654        if (stackId == HOME_STACK_ID) {
7655            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7656                    new RuntimeException("here").fillInStackTrace());
7657        }
7658        synchronized (this) {
7659            long ident = Binder.clearCallingIdentity();
7660            try {
7661                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7662                        + stackId + " toTop=" + toTop);
7663                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7664            } finally {
7665                Binder.restoreCallingIdentity(ident);
7666            }
7667        }
7668    }
7669
7670    @Override
7671    public void resizeStack(int stackBoxId, Rect bounds) {
7672        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7673                "resizeStackBox()");
7674        long ident = Binder.clearCallingIdentity();
7675        try {
7676            mWindowManager.resizeStack(stackBoxId, bounds);
7677        } finally {
7678            Binder.restoreCallingIdentity(ident);
7679        }
7680    }
7681
7682    @Override
7683    public List<StackInfo> getAllStackInfos() {
7684        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7685                "getAllStackInfos()");
7686        long ident = Binder.clearCallingIdentity();
7687        try {
7688            synchronized (this) {
7689                return mStackSupervisor.getAllStackInfosLocked();
7690            }
7691        } finally {
7692            Binder.restoreCallingIdentity(ident);
7693        }
7694    }
7695
7696    @Override
7697    public StackInfo getStackInfo(int stackId) {
7698        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7699                "getStackInfo()");
7700        long ident = Binder.clearCallingIdentity();
7701        try {
7702            synchronized (this) {
7703                return mStackSupervisor.getStackInfoLocked(stackId);
7704            }
7705        } finally {
7706            Binder.restoreCallingIdentity(ident);
7707        }
7708    }
7709
7710    @Override
7711    public boolean isInHomeStack(int taskId) {
7712        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7713                "getStackInfo()");
7714        long ident = Binder.clearCallingIdentity();
7715        try {
7716            synchronized (this) {
7717                TaskRecord tr = recentTaskForIdLocked(taskId);
7718                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7719            }
7720        } finally {
7721            Binder.restoreCallingIdentity(ident);
7722        }
7723    }
7724
7725    @Override
7726    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7727        synchronized(this) {
7728            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7729        }
7730    }
7731
7732    private boolean isLockTaskAuthorized(String pkg) {
7733        final DevicePolicyManager dpm = (DevicePolicyManager)
7734                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7735        try {
7736            int uid = mContext.getPackageManager().getPackageUid(pkg,
7737                    Binder.getCallingUserHandle().getIdentifier());
7738            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
7739        } catch (NameNotFoundException e) {
7740            return false;
7741        }
7742    }
7743
7744    void startLockTaskMode(TaskRecord task) {
7745        final String pkg;
7746        synchronized (this) {
7747            pkg = task.intent.getComponent().getPackageName();
7748        }
7749        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
7750        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
7751            final TaskRecord taskRecord = task;
7752            mHandler.post(new Runnable() {
7753                @Override
7754                public void run() {
7755                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
7756                }
7757            });
7758            return;
7759        }
7760        long ident = Binder.clearCallingIdentity();
7761        try {
7762            synchronized (this) {
7763                // Since we lost lock on task, make sure it is still there.
7764                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7765                if (task != null) {
7766                    if ((mFocusedActivity == null) || (task != mFocusedActivity.task)) {
7767                        throw new IllegalArgumentException("Invalid task, not in foreground");
7768                    }
7769                    mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated);
7770                }
7771            }
7772        } finally {
7773            Binder.restoreCallingIdentity(ident);
7774        }
7775    }
7776
7777    @Override
7778    public void startLockTaskMode(int taskId) {
7779        final TaskRecord task;
7780        long ident = Binder.clearCallingIdentity();
7781        try {
7782            synchronized (this) {
7783                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7784            }
7785        } finally {
7786            Binder.restoreCallingIdentity(ident);
7787        }
7788        if (task != null) {
7789            startLockTaskMode(task);
7790        }
7791    }
7792
7793    @Override
7794    public void startLockTaskMode(IBinder token) {
7795        final TaskRecord task;
7796        long ident = Binder.clearCallingIdentity();
7797        try {
7798            synchronized (this) {
7799                final ActivityRecord r = ActivityRecord.forToken(token);
7800                if (r == null) {
7801                    return;
7802                }
7803                task = r.task;
7804            }
7805        } finally {
7806            Binder.restoreCallingIdentity(ident);
7807        }
7808        if (task != null) {
7809            startLockTaskMode(task);
7810        }
7811    }
7812
7813    @Override
7814    public void startLockTaskModeOnCurrent() throws RemoteException {
7815        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7816        ActivityRecord r = null;
7817        synchronized (this) {
7818            r = mStackSupervisor.topRunningActivityLocked();
7819        }
7820        startLockTaskMode(r.task);
7821    }
7822
7823    @Override
7824    public void stopLockTaskMode() {
7825        // Verify that the user matches the package of the intent for the TaskRecord
7826        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
7827        // and stopLockTaskMode.
7828        final int callingUid = Binder.getCallingUid();
7829        if (callingUid != Process.SYSTEM_UID) {
7830            try {
7831                String pkg =
7832                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
7833                int uid = mContext.getPackageManager().getPackageUid(pkg,
7834                        Binder.getCallingUserHandle().getIdentifier());
7835                if (uid != callingUid) {
7836                    throw new SecurityException("Invalid uid, expected " + uid);
7837                }
7838            } catch (NameNotFoundException e) {
7839                Log.d(TAG, "stopLockTaskMode " + e);
7840                return;
7841            }
7842        }
7843        long ident = Binder.clearCallingIdentity();
7844        try {
7845            Log.d(TAG, "stopLockTaskMode");
7846            // Stop lock task
7847            synchronized (this) {
7848                mStackSupervisor.setLockTaskModeLocked(null, false);
7849            }
7850        } finally {
7851            Binder.restoreCallingIdentity(ident);
7852        }
7853    }
7854
7855    @Override
7856    public void stopLockTaskModeOnCurrent() throws RemoteException {
7857        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7858        long ident = Binder.clearCallingIdentity();
7859        try {
7860            stopLockTaskMode();
7861        } finally {
7862            Binder.restoreCallingIdentity(ident);
7863        }
7864    }
7865
7866    @Override
7867    public boolean isInLockTaskMode() {
7868        synchronized (this) {
7869            return mStackSupervisor.isInLockTaskMode();
7870        }
7871    }
7872
7873    // =========================================================
7874    // CONTENT PROVIDERS
7875    // =========================================================
7876
7877    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7878        List<ProviderInfo> providers = null;
7879        try {
7880            providers = AppGlobals.getPackageManager().
7881                queryContentProviders(app.processName, app.uid,
7882                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7883        } catch (RemoteException ex) {
7884        }
7885        if (DEBUG_MU)
7886            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7887        int userId = app.userId;
7888        if (providers != null) {
7889            int N = providers.size();
7890            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7891            for (int i=0; i<N; i++) {
7892                ProviderInfo cpi =
7893                    (ProviderInfo)providers.get(i);
7894                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7895                        cpi.name, cpi.flags);
7896                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7897                    // This is a singleton provider, but a user besides the
7898                    // default user is asking to initialize a process it runs
7899                    // in...  well, no, it doesn't actually run in this process,
7900                    // it runs in the process of the default user.  Get rid of it.
7901                    providers.remove(i);
7902                    N--;
7903                    i--;
7904                    continue;
7905                }
7906
7907                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7908                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7909                if (cpr == null) {
7910                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7911                    mProviderMap.putProviderByClass(comp, cpr);
7912                }
7913                if (DEBUG_MU)
7914                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7915                app.pubProviders.put(cpi.name, cpr);
7916                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7917                    // Don't add this if it is a platform component that is marked
7918                    // to run in multiple processes, because this is actually
7919                    // part of the framework so doesn't make sense to track as a
7920                    // separate apk in the process.
7921                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
7922                            mProcessStats);
7923                }
7924                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7925            }
7926        }
7927        return providers;
7928    }
7929
7930    /**
7931     * Check if {@link ProcessRecord} has a possible chance at accessing the
7932     * given {@link ProviderInfo}. Final permission checking is always done
7933     * in {@link ContentProvider}.
7934     */
7935    private final String checkContentProviderPermissionLocked(
7936            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
7937        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7938        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7939        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7940        // Looking for cross-user grants before to enforce the typical cross-users permissions
7941        if (userId != UserHandle.getUserId(callingUid)) {
7942            if (perms != null) {
7943                for (GrantUri grantUri : perms.keySet()) {
7944                    if (grantUri.sourceUserId == userId) {
7945                        String authority = grantUri.uri.getAuthority();
7946                        if (authority.equals(cpi.authority)) {
7947                            return null;
7948                        }
7949                    }
7950                }
7951            }
7952        }
7953        if (checkUser) {
7954            userId = handleIncomingUser(callingPid, callingUid, userId,
7955                    false, true, "checkContentProviderPermissionLocked " + cpi.authority, null);
7956        }
7957        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7958                cpi.applicationInfo.uid, cpi.exported)
7959                == PackageManager.PERMISSION_GRANTED) {
7960            return null;
7961        }
7962        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7963                cpi.applicationInfo.uid, cpi.exported)
7964                == PackageManager.PERMISSION_GRANTED) {
7965            return null;
7966        }
7967
7968        PathPermission[] pps = cpi.pathPermissions;
7969        if (pps != null) {
7970            int i = pps.length;
7971            while (i > 0) {
7972                i--;
7973                PathPermission pp = pps[i];
7974                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7975                        cpi.applicationInfo.uid, cpi.exported)
7976                        == PackageManager.PERMISSION_GRANTED) {
7977                    return null;
7978                }
7979                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7980                        cpi.applicationInfo.uid, cpi.exported)
7981                        == PackageManager.PERMISSION_GRANTED) {
7982                    return null;
7983                }
7984            }
7985        }
7986
7987        if (perms != null) {
7988            for (GrantUri grantUri : perms.keySet()) {
7989                if (grantUri.uri.getAuthority().equals(cpi.authority)) {
7990                    return null;
7991                }
7992            }
7993        }
7994
7995        String msg;
7996        if (!cpi.exported) {
7997            msg = "Permission Denial: opening provider " + cpi.name
7998                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7999                    + ", uid=" + callingUid + ") that is not exported from uid "
8000                    + cpi.applicationInfo.uid;
8001        } else {
8002            msg = "Permission Denial: opening provider " + cpi.name
8003                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8004                    + ", uid=" + callingUid + ") requires "
8005                    + cpi.readPermission + " or " + cpi.writePermission;
8006        }
8007        Slog.w(TAG, msg);
8008        return msg;
8009    }
8010
8011    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8012            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8013        if (r != null) {
8014            for (int i=0; i<r.conProviders.size(); i++) {
8015                ContentProviderConnection conn = r.conProviders.get(i);
8016                if (conn.provider == cpr) {
8017                    if (DEBUG_PROVIDER) Slog.v(TAG,
8018                            "Adding provider requested by "
8019                            + r.processName + " from process "
8020                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8021                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8022                    if (stable) {
8023                        conn.stableCount++;
8024                        conn.numStableIncs++;
8025                    } else {
8026                        conn.unstableCount++;
8027                        conn.numUnstableIncs++;
8028                    }
8029                    return conn;
8030                }
8031            }
8032            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8033            if (stable) {
8034                conn.stableCount = 1;
8035                conn.numStableIncs = 1;
8036            } else {
8037                conn.unstableCount = 1;
8038                conn.numUnstableIncs = 1;
8039            }
8040            cpr.connections.add(conn);
8041            r.conProviders.add(conn);
8042            return conn;
8043        }
8044        cpr.addExternalProcessHandleLocked(externalProcessToken);
8045        return null;
8046    }
8047
8048    boolean decProviderCountLocked(ContentProviderConnection conn,
8049            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8050        if (conn != null) {
8051            cpr = conn.provider;
8052            if (DEBUG_PROVIDER) Slog.v(TAG,
8053                    "Removing provider requested by "
8054                    + conn.client.processName + " from process "
8055                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8056                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8057            if (stable) {
8058                conn.stableCount--;
8059            } else {
8060                conn.unstableCount--;
8061            }
8062            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8063                cpr.connections.remove(conn);
8064                conn.client.conProviders.remove(conn);
8065                return true;
8066            }
8067            return false;
8068        }
8069        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8070        return false;
8071    }
8072
8073    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8074            String name, IBinder token, boolean stable, int userId) {
8075        ContentProviderRecord cpr;
8076        ContentProviderConnection conn = null;
8077        ProviderInfo cpi = null;
8078
8079        synchronized(this) {
8080            ProcessRecord r = null;
8081            if (caller != null) {
8082                r = getRecordForAppLocked(caller);
8083                if (r == null) {
8084                    throw new SecurityException(
8085                            "Unable to find app for caller " + caller
8086                          + " (pid=" + Binder.getCallingPid()
8087                          + ") when getting content provider " + name);
8088                }
8089            }
8090
8091            boolean checkCrossUser = true;
8092
8093            // First check if this content provider has been published...
8094            cpr = mProviderMap.getProviderByName(name, userId);
8095            // If that didn't work, check if it exists for user 0 and then
8096            // verify that it's a singleton provider before using it.
8097            if (cpr == null && userId != UserHandle.USER_OWNER) {
8098                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8099                if (cpr != null) {
8100                    cpi = cpr.info;
8101                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8102                            cpi.name, cpi.flags)
8103                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8104                        userId = UserHandle.USER_OWNER;
8105                        checkCrossUser = false;
8106                    } else {
8107                        cpr = null;
8108                        cpi = null;
8109                    }
8110                }
8111            }
8112
8113            boolean providerRunning = cpr != null;
8114            if (providerRunning) {
8115                cpi = cpr.info;
8116                String msg;
8117                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8118                        != null) {
8119                    throw new SecurityException(msg);
8120                }
8121
8122                if (r != null && cpr.canRunHere(r)) {
8123                    // This provider has been published or is in the process
8124                    // of being published...  but it is also allowed to run
8125                    // in the caller's process, so don't make a connection
8126                    // and just let the caller instantiate its own instance.
8127                    ContentProviderHolder holder = cpr.newHolder(null);
8128                    // don't give caller the provider object, it needs
8129                    // to make its own.
8130                    holder.provider = null;
8131                    return holder;
8132                }
8133
8134                final long origId = Binder.clearCallingIdentity();
8135
8136                // In this case the provider instance already exists, so we can
8137                // return it right away.
8138                conn = incProviderCountLocked(r, cpr, token, stable);
8139                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8140                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8141                        // If this is a perceptible app accessing the provider,
8142                        // make sure to count it as being accessed and thus
8143                        // back up on the LRU list.  This is good because
8144                        // content providers are often expensive to start.
8145                        updateLruProcessLocked(cpr.proc, false, null);
8146                    }
8147                }
8148
8149                if (cpr.proc != null) {
8150                    if (false) {
8151                        if (cpr.name.flattenToShortString().equals(
8152                                "com.android.providers.calendar/.CalendarProvider2")) {
8153                            Slog.v(TAG, "****************** KILLING "
8154                                + cpr.name.flattenToShortString());
8155                            Process.killProcess(cpr.proc.pid);
8156                        }
8157                    }
8158                    boolean success = updateOomAdjLocked(cpr.proc);
8159                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8160                    // NOTE: there is still a race here where a signal could be
8161                    // pending on the process even though we managed to update its
8162                    // adj level.  Not sure what to do about this, but at least
8163                    // the race is now smaller.
8164                    if (!success) {
8165                        // Uh oh...  it looks like the provider's process
8166                        // has been killed on us.  We need to wait for a new
8167                        // process to be started, and make sure its death
8168                        // doesn't kill our process.
8169                        Slog.i(TAG,
8170                                "Existing provider " + cpr.name.flattenToShortString()
8171                                + " is crashing; detaching " + r);
8172                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8173                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8174                        if (!lastRef) {
8175                            // This wasn't the last ref our process had on
8176                            // the provider...  we have now been killed, bail.
8177                            return null;
8178                        }
8179                        providerRunning = false;
8180                        conn = null;
8181                    }
8182                }
8183
8184                Binder.restoreCallingIdentity(origId);
8185            }
8186
8187            boolean singleton;
8188            if (!providerRunning) {
8189                try {
8190                    cpi = AppGlobals.getPackageManager().
8191                        resolveContentProvider(name,
8192                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8193                } catch (RemoteException ex) {
8194                }
8195                if (cpi == null) {
8196                    return null;
8197                }
8198                // If the provider is a singleton AND
8199                // (it's a call within the same user || the provider is a
8200                // privileged app)
8201                // Then allow connecting to the singleton provider
8202                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8203                        cpi.name, cpi.flags)
8204                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8205                if (singleton) {
8206                    userId = UserHandle.USER_OWNER;
8207                }
8208                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8209
8210                String msg;
8211                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8212                        != null) {
8213                    throw new SecurityException(msg);
8214                }
8215
8216                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8217                        && !cpi.processName.equals("system")) {
8218                    // If this content provider does not run in the system
8219                    // process, and the system is not yet ready to run other
8220                    // processes, then fail fast instead of hanging.
8221                    throw new IllegalArgumentException(
8222                            "Attempt to launch content provider before system ready");
8223                }
8224
8225                // Make sure that the user who owns this provider is started.  If not,
8226                // we don't want to allow it to run.
8227                if (mStartedUsers.get(userId) == null) {
8228                    Slog.w(TAG, "Unable to launch app "
8229                            + cpi.applicationInfo.packageName + "/"
8230                            + cpi.applicationInfo.uid + " for provider "
8231                            + name + ": user " + userId + " is stopped");
8232                    return null;
8233                }
8234
8235                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8236                cpr = mProviderMap.getProviderByClass(comp, userId);
8237                final boolean firstClass = cpr == null;
8238                if (firstClass) {
8239                    try {
8240                        ApplicationInfo ai =
8241                            AppGlobals.getPackageManager().
8242                                getApplicationInfo(
8243                                        cpi.applicationInfo.packageName,
8244                                        STOCK_PM_FLAGS, userId);
8245                        if (ai == null) {
8246                            Slog.w(TAG, "No package info for content provider "
8247                                    + cpi.name);
8248                            return null;
8249                        }
8250                        ai = getAppInfoForUser(ai, userId);
8251                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8252                    } catch (RemoteException ex) {
8253                        // pm is in same process, this will never happen.
8254                    }
8255                }
8256
8257                if (r != null && cpr.canRunHere(r)) {
8258                    // If this is a multiprocess provider, then just return its
8259                    // info and allow the caller to instantiate it.  Only do
8260                    // this if the provider is the same user as the caller's
8261                    // process, or can run as root (so can be in any process).
8262                    return cpr.newHolder(null);
8263                }
8264
8265                if (DEBUG_PROVIDER) {
8266                    RuntimeException e = new RuntimeException("here");
8267                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8268                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8269                }
8270
8271                // This is single process, and our app is now connecting to it.
8272                // See if we are already in the process of launching this
8273                // provider.
8274                final int N = mLaunchingProviders.size();
8275                int i;
8276                for (i=0; i<N; i++) {
8277                    if (mLaunchingProviders.get(i) == cpr) {
8278                        break;
8279                    }
8280                }
8281
8282                // If the provider is not already being launched, then get it
8283                // started.
8284                if (i >= N) {
8285                    final long origId = Binder.clearCallingIdentity();
8286
8287                    try {
8288                        // Content provider is now in use, its package can't be stopped.
8289                        try {
8290                            AppGlobals.getPackageManager().setPackageStoppedState(
8291                                    cpr.appInfo.packageName, false, userId);
8292                        } catch (RemoteException e) {
8293                        } catch (IllegalArgumentException e) {
8294                            Slog.w(TAG, "Failed trying to unstop package "
8295                                    + cpr.appInfo.packageName + ": " + e);
8296                        }
8297
8298                        // Use existing process if already started
8299                        ProcessRecord proc = getProcessRecordLocked(
8300                                cpi.processName, cpr.appInfo.uid, false);
8301                        if (proc != null && proc.thread != null) {
8302                            if (DEBUG_PROVIDER) {
8303                                Slog.d(TAG, "Installing in existing process " + proc);
8304                            }
8305                            proc.pubProviders.put(cpi.name, cpr);
8306                            try {
8307                                proc.thread.scheduleInstallProvider(cpi);
8308                            } catch (RemoteException e) {
8309                            }
8310                        } else {
8311                            proc = startProcessLocked(cpi.processName,
8312                                    cpr.appInfo, false, 0, "content provider",
8313                                    new ComponentName(cpi.applicationInfo.packageName,
8314                                            cpi.name), false, false, false);
8315                            if (proc == null) {
8316                                Slog.w(TAG, "Unable to launch app "
8317                                        + cpi.applicationInfo.packageName + "/"
8318                                        + cpi.applicationInfo.uid + " for provider "
8319                                        + name + ": process is bad");
8320                                return null;
8321                            }
8322                        }
8323                        cpr.launchingApp = proc;
8324                        mLaunchingProviders.add(cpr);
8325                    } finally {
8326                        Binder.restoreCallingIdentity(origId);
8327                    }
8328                }
8329
8330                // Make sure the provider is published (the same provider class
8331                // may be published under multiple names).
8332                if (firstClass) {
8333                    mProviderMap.putProviderByClass(comp, cpr);
8334                }
8335
8336                mProviderMap.putProviderByName(name, cpr);
8337                conn = incProviderCountLocked(r, cpr, token, stable);
8338                if (conn != null) {
8339                    conn.waiting = true;
8340                }
8341            }
8342        }
8343
8344        // Wait for the provider to be published...
8345        synchronized (cpr) {
8346            while (cpr.provider == null) {
8347                if (cpr.launchingApp == null) {
8348                    Slog.w(TAG, "Unable to launch app "
8349                            + cpi.applicationInfo.packageName + "/"
8350                            + cpi.applicationInfo.uid + " for provider "
8351                            + name + ": launching app became null");
8352                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8353                            UserHandle.getUserId(cpi.applicationInfo.uid),
8354                            cpi.applicationInfo.packageName,
8355                            cpi.applicationInfo.uid, name);
8356                    return null;
8357                }
8358                try {
8359                    if (DEBUG_MU) {
8360                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8361                                + cpr.launchingApp);
8362                    }
8363                    if (conn != null) {
8364                        conn.waiting = true;
8365                    }
8366                    cpr.wait();
8367                } catch (InterruptedException ex) {
8368                } finally {
8369                    if (conn != null) {
8370                        conn.waiting = false;
8371                    }
8372                }
8373            }
8374        }
8375        return cpr != null ? cpr.newHolder(conn) : null;
8376    }
8377
8378    @Override
8379    public final ContentProviderHolder getContentProvider(
8380            IApplicationThread caller, String name, int userId, boolean stable) {
8381        enforceNotIsolatedCaller("getContentProvider");
8382        if (caller == null) {
8383            String msg = "null IApplicationThread when getting content provider "
8384                    + name;
8385            Slog.w(TAG, msg);
8386            throw new SecurityException(msg);
8387        }
8388        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8389        // with cross-user grant.
8390        return getContentProviderImpl(caller, name, null, stable, userId);
8391    }
8392
8393    public ContentProviderHolder getContentProviderExternal(
8394            String name, int userId, IBinder token) {
8395        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8396            "Do not have permission in call getContentProviderExternal()");
8397        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8398                false, true, "getContentProvider", null);
8399        return getContentProviderExternalUnchecked(name, token, userId);
8400    }
8401
8402    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8403            IBinder token, int userId) {
8404        return getContentProviderImpl(null, name, token, true, userId);
8405    }
8406
8407    /**
8408     * Drop a content provider from a ProcessRecord's bookkeeping
8409     */
8410    public void removeContentProvider(IBinder connection, boolean stable) {
8411        enforceNotIsolatedCaller("removeContentProvider");
8412        long ident = Binder.clearCallingIdentity();
8413        try {
8414            synchronized (this) {
8415                ContentProviderConnection conn;
8416                try {
8417                    conn = (ContentProviderConnection)connection;
8418                } catch (ClassCastException e) {
8419                    String msg ="removeContentProvider: " + connection
8420                            + " not a ContentProviderConnection";
8421                    Slog.w(TAG, msg);
8422                    throw new IllegalArgumentException(msg);
8423                }
8424                if (conn == null) {
8425                    throw new NullPointerException("connection is null");
8426                }
8427                if (decProviderCountLocked(conn, null, null, stable)) {
8428                    updateOomAdjLocked();
8429                }
8430            }
8431        } finally {
8432            Binder.restoreCallingIdentity(ident);
8433        }
8434    }
8435
8436    public void removeContentProviderExternal(String name, IBinder token) {
8437        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8438            "Do not have permission in call removeContentProviderExternal()");
8439        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8440    }
8441
8442    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8443        synchronized (this) {
8444            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8445            if(cpr == null) {
8446                //remove from mProvidersByClass
8447                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8448                return;
8449            }
8450
8451            //update content provider record entry info
8452            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8453            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8454            if (localCpr.hasExternalProcessHandles()) {
8455                if (localCpr.removeExternalProcessHandleLocked(token)) {
8456                    updateOomAdjLocked();
8457                } else {
8458                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8459                            + " with no external reference for token: "
8460                            + token + ".");
8461                }
8462            } else {
8463                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8464                        + " with no external references.");
8465            }
8466        }
8467    }
8468
8469    public final void publishContentProviders(IApplicationThread caller,
8470            List<ContentProviderHolder> providers) {
8471        if (providers == null) {
8472            return;
8473        }
8474
8475        enforceNotIsolatedCaller("publishContentProviders");
8476        synchronized (this) {
8477            final ProcessRecord r = getRecordForAppLocked(caller);
8478            if (DEBUG_MU)
8479                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8480            if (r == null) {
8481                throw new SecurityException(
8482                        "Unable to find app for caller " + caller
8483                      + " (pid=" + Binder.getCallingPid()
8484                      + ") when publishing content providers");
8485            }
8486
8487            final long origId = Binder.clearCallingIdentity();
8488
8489            final int N = providers.size();
8490            for (int i=0; i<N; i++) {
8491                ContentProviderHolder src = providers.get(i);
8492                if (src == null || src.info == null || src.provider == null) {
8493                    continue;
8494                }
8495                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8496                if (DEBUG_MU)
8497                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8498                if (dst != null) {
8499                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8500                    mProviderMap.putProviderByClass(comp, dst);
8501                    String names[] = dst.info.authority.split(";");
8502                    for (int j = 0; j < names.length; j++) {
8503                        mProviderMap.putProviderByName(names[j], dst);
8504                    }
8505
8506                    int NL = mLaunchingProviders.size();
8507                    int j;
8508                    for (j=0; j<NL; j++) {
8509                        if (mLaunchingProviders.get(j) == dst) {
8510                            mLaunchingProviders.remove(j);
8511                            j--;
8512                            NL--;
8513                        }
8514                    }
8515                    synchronized (dst) {
8516                        dst.provider = src.provider;
8517                        dst.proc = r;
8518                        dst.notifyAll();
8519                    }
8520                    updateOomAdjLocked(r);
8521                }
8522            }
8523
8524            Binder.restoreCallingIdentity(origId);
8525        }
8526    }
8527
8528    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8529        ContentProviderConnection conn;
8530        try {
8531            conn = (ContentProviderConnection)connection;
8532        } catch (ClassCastException e) {
8533            String msg ="refContentProvider: " + connection
8534                    + " not a ContentProviderConnection";
8535            Slog.w(TAG, msg);
8536            throw new IllegalArgumentException(msg);
8537        }
8538        if (conn == null) {
8539            throw new NullPointerException("connection is null");
8540        }
8541
8542        synchronized (this) {
8543            if (stable > 0) {
8544                conn.numStableIncs += stable;
8545            }
8546            stable = conn.stableCount + stable;
8547            if (stable < 0) {
8548                throw new IllegalStateException("stableCount < 0: " + stable);
8549            }
8550
8551            if (unstable > 0) {
8552                conn.numUnstableIncs += unstable;
8553            }
8554            unstable = conn.unstableCount + unstable;
8555            if (unstable < 0) {
8556                throw new IllegalStateException("unstableCount < 0: " + unstable);
8557            }
8558
8559            if ((stable+unstable) <= 0) {
8560                throw new IllegalStateException("ref counts can't go to zero here: stable="
8561                        + stable + " unstable=" + unstable);
8562            }
8563            conn.stableCount = stable;
8564            conn.unstableCount = unstable;
8565            return !conn.dead;
8566        }
8567    }
8568
8569    public void unstableProviderDied(IBinder connection) {
8570        ContentProviderConnection conn;
8571        try {
8572            conn = (ContentProviderConnection)connection;
8573        } catch (ClassCastException e) {
8574            String msg ="refContentProvider: " + connection
8575                    + " not a ContentProviderConnection";
8576            Slog.w(TAG, msg);
8577            throw new IllegalArgumentException(msg);
8578        }
8579        if (conn == null) {
8580            throw new NullPointerException("connection is null");
8581        }
8582
8583        // Safely retrieve the content provider associated with the connection.
8584        IContentProvider provider;
8585        synchronized (this) {
8586            provider = conn.provider.provider;
8587        }
8588
8589        if (provider == null) {
8590            // Um, yeah, we're way ahead of you.
8591            return;
8592        }
8593
8594        // Make sure the caller is being honest with us.
8595        if (provider.asBinder().pingBinder()) {
8596            // Er, no, still looks good to us.
8597            synchronized (this) {
8598                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8599                        + " says " + conn + " died, but we don't agree");
8600                return;
8601            }
8602        }
8603
8604        // Well look at that!  It's dead!
8605        synchronized (this) {
8606            if (conn.provider.provider != provider) {
8607                // But something changed...  good enough.
8608                return;
8609            }
8610
8611            ProcessRecord proc = conn.provider.proc;
8612            if (proc == null || proc.thread == null) {
8613                // Seems like the process is already cleaned up.
8614                return;
8615            }
8616
8617            // As far as we're concerned, this is just like receiving a
8618            // death notification...  just a bit prematurely.
8619            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8620                    + ") early provider death");
8621            final long ident = Binder.clearCallingIdentity();
8622            try {
8623                appDiedLocked(proc, proc.pid, proc.thread);
8624            } finally {
8625                Binder.restoreCallingIdentity(ident);
8626            }
8627        }
8628    }
8629
8630    @Override
8631    public void appNotRespondingViaProvider(IBinder connection) {
8632        enforceCallingPermission(
8633                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8634
8635        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8636        if (conn == null) {
8637            Slog.w(TAG, "ContentProviderConnection is null");
8638            return;
8639        }
8640
8641        final ProcessRecord host = conn.provider.proc;
8642        if (host == null) {
8643            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8644            return;
8645        }
8646
8647        final long token = Binder.clearCallingIdentity();
8648        try {
8649            appNotResponding(host, null, null, false, "ContentProvider not responding");
8650        } finally {
8651            Binder.restoreCallingIdentity(token);
8652        }
8653    }
8654
8655    public final void installSystemProviders() {
8656        List<ProviderInfo> providers;
8657        synchronized (this) {
8658            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8659            providers = generateApplicationProvidersLocked(app);
8660            if (providers != null) {
8661                for (int i=providers.size()-1; i>=0; i--) {
8662                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8663                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8664                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8665                                + ": not system .apk");
8666                        providers.remove(i);
8667                    }
8668                }
8669            }
8670        }
8671        if (providers != null) {
8672            mSystemThread.installSystemProviders(providers);
8673        }
8674
8675        mCoreSettingsObserver = new CoreSettingsObserver(this);
8676
8677        mUsageStatsService.monitorPackages();
8678    }
8679
8680    /**
8681     * Allows app to retrieve the MIME type of a URI without having permission
8682     * to access its content provider.
8683     *
8684     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8685     *
8686     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8687     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8688     */
8689    public String getProviderMimeType(Uri uri, int userId) {
8690        enforceNotIsolatedCaller("getProviderMimeType");
8691        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8692                userId, false, true, "getProviderMimeType", null);
8693        final String name = uri.getAuthority();
8694        final long ident = Binder.clearCallingIdentity();
8695        ContentProviderHolder holder = null;
8696
8697        try {
8698            holder = getContentProviderExternalUnchecked(name, null, userId);
8699            if (holder != null) {
8700                return holder.provider.getType(uri);
8701            }
8702        } catch (RemoteException e) {
8703            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8704            return null;
8705        } finally {
8706            if (holder != null) {
8707                removeContentProviderExternalUnchecked(name, null, userId);
8708            }
8709            Binder.restoreCallingIdentity(ident);
8710        }
8711
8712        return null;
8713    }
8714
8715    // =========================================================
8716    // GLOBAL MANAGEMENT
8717    // =========================================================
8718
8719    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8720            boolean isolated) {
8721        String proc = customProcess != null ? customProcess : info.processName;
8722        BatteryStatsImpl.Uid.Proc ps = null;
8723        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8724        int uid = info.uid;
8725        if (isolated) {
8726            int userId = UserHandle.getUserId(uid);
8727            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8728            while (true) {
8729                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8730                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8731                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8732                }
8733                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8734                mNextIsolatedProcessUid++;
8735                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8736                    // No process for this uid, use it.
8737                    break;
8738                }
8739                stepsLeft--;
8740                if (stepsLeft <= 0) {
8741                    return null;
8742                }
8743            }
8744        }
8745        return new ProcessRecord(stats, info, proc, uid);
8746    }
8747
8748    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
8749            String abiOverride) {
8750        ProcessRecord app;
8751        if (!isolated) {
8752            app = getProcessRecordLocked(info.processName, info.uid, true);
8753        } else {
8754            app = null;
8755        }
8756
8757        if (app == null) {
8758            app = newProcessRecordLocked(info, null, isolated);
8759            mProcessNames.put(info.processName, app.uid, app);
8760            if (isolated) {
8761                mIsolatedProcesses.put(app.uid, app);
8762            }
8763            updateLruProcessLocked(app, false, null);
8764            updateOomAdjLocked();
8765        }
8766
8767        // This package really, really can not be stopped.
8768        try {
8769            AppGlobals.getPackageManager().setPackageStoppedState(
8770                    info.packageName, false, UserHandle.getUserId(app.uid));
8771        } catch (RemoteException e) {
8772        } catch (IllegalArgumentException e) {
8773            Slog.w(TAG, "Failed trying to unstop package "
8774                    + info.packageName + ": " + e);
8775        }
8776
8777        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8778                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8779            app.persistent = true;
8780            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8781        }
8782        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8783            mPersistentStartingProcesses.add(app);
8784            startProcessLocked(app, "added application", app.processName,
8785                    abiOverride);
8786        }
8787
8788        return app;
8789    }
8790
8791    public void unhandledBack() {
8792        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8793                "unhandledBack()");
8794
8795        synchronized(this) {
8796            final long origId = Binder.clearCallingIdentity();
8797            try {
8798                getFocusedStack().unhandledBackLocked();
8799            } finally {
8800                Binder.restoreCallingIdentity(origId);
8801            }
8802        }
8803    }
8804
8805    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8806        enforceNotIsolatedCaller("openContentUri");
8807        final int userId = UserHandle.getCallingUserId();
8808        String name = uri.getAuthority();
8809        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8810        ParcelFileDescriptor pfd = null;
8811        if (cph != null) {
8812            // We record the binder invoker's uid in thread-local storage before
8813            // going to the content provider to open the file.  Later, in the code
8814            // that handles all permissions checks, we look for this uid and use
8815            // that rather than the Activity Manager's own uid.  The effect is that
8816            // we do the check against the caller's permissions even though it looks
8817            // to the content provider like the Activity Manager itself is making
8818            // the request.
8819            sCallerIdentity.set(new Identity(
8820                    Binder.getCallingPid(), Binder.getCallingUid()));
8821            try {
8822                pfd = cph.provider.openFile(null, uri, "r", null);
8823            } catch (FileNotFoundException e) {
8824                // do nothing; pfd will be returned null
8825            } finally {
8826                // Ensure that whatever happens, we clean up the identity state
8827                sCallerIdentity.remove();
8828            }
8829
8830            // We've got the fd now, so we're done with the provider.
8831            removeContentProviderExternalUnchecked(name, null, userId);
8832        } else {
8833            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8834        }
8835        return pfd;
8836    }
8837
8838    // Actually is sleeping or shutting down or whatever else in the future
8839    // is an inactive state.
8840    public boolean isSleepingOrShuttingDown() {
8841        return mSleeping || mShuttingDown;
8842    }
8843
8844    public boolean isSleeping() {
8845        return mSleeping;
8846    }
8847
8848    void goingToSleep() {
8849        synchronized(this) {
8850            mWentToSleep = true;
8851            updateEventDispatchingLocked();
8852            goToSleepIfNeededLocked();
8853        }
8854    }
8855
8856    void finishRunningVoiceLocked() {
8857        if (mRunningVoice) {
8858            mRunningVoice = false;
8859            goToSleepIfNeededLocked();
8860        }
8861    }
8862
8863    void goToSleepIfNeededLocked() {
8864        if (mWentToSleep && !mRunningVoice) {
8865            if (!mSleeping) {
8866                mSleeping = true;
8867                mStackSupervisor.goingToSleepLocked();
8868
8869                // Initialize the wake times of all processes.
8870                checkExcessivePowerUsageLocked(false);
8871                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8872                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8873                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8874            }
8875        }
8876    }
8877
8878    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
8879        mTaskPersister.notify(task, flush);
8880    }
8881
8882    @Override
8883    public boolean shutdown(int timeout) {
8884        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8885                != PackageManager.PERMISSION_GRANTED) {
8886            throw new SecurityException("Requires permission "
8887                    + android.Manifest.permission.SHUTDOWN);
8888        }
8889
8890        boolean timedout = false;
8891
8892        synchronized(this) {
8893            mShuttingDown = true;
8894            updateEventDispatchingLocked();
8895            timedout = mStackSupervisor.shutdownLocked(timeout);
8896        }
8897
8898        mAppOpsService.shutdown();
8899        mUsageStatsService.shutdown();
8900        mBatteryStatsService.shutdown();
8901        synchronized (this) {
8902            mProcessStats.shutdownLocked();
8903        }
8904        notifyTaskPersisterLocked(null, true);
8905
8906        return timedout;
8907    }
8908
8909    public final void activitySlept(IBinder token) {
8910        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8911
8912        final long origId = Binder.clearCallingIdentity();
8913
8914        synchronized (this) {
8915            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8916            if (r != null) {
8917                mStackSupervisor.activitySleptLocked(r);
8918            }
8919        }
8920
8921        Binder.restoreCallingIdentity(origId);
8922    }
8923
8924    void logLockScreen(String msg) {
8925        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8926                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8927                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8928                mStackSupervisor.mDismissKeyguardOnNextActivity);
8929    }
8930
8931    private void comeOutOfSleepIfNeededLocked() {
8932        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
8933            if (mSleeping) {
8934                mSleeping = false;
8935                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8936            }
8937        }
8938    }
8939
8940    void wakingUp() {
8941        synchronized(this) {
8942            mWentToSleep = false;
8943            updateEventDispatchingLocked();
8944            comeOutOfSleepIfNeededLocked();
8945        }
8946    }
8947
8948    void startRunningVoiceLocked() {
8949        if (!mRunningVoice) {
8950            mRunningVoice = true;
8951            comeOutOfSleepIfNeededLocked();
8952        }
8953    }
8954
8955    private void updateEventDispatchingLocked() {
8956        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8957    }
8958
8959    public void setLockScreenShown(boolean shown) {
8960        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8961                != PackageManager.PERMISSION_GRANTED) {
8962            throw new SecurityException("Requires permission "
8963                    + android.Manifest.permission.DEVICE_POWER);
8964        }
8965
8966        synchronized(this) {
8967            long ident = Binder.clearCallingIdentity();
8968            try {
8969                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8970                mLockScreenShown = shown;
8971                comeOutOfSleepIfNeededLocked();
8972            } finally {
8973                Binder.restoreCallingIdentity(ident);
8974            }
8975        }
8976    }
8977
8978    public void stopAppSwitches() {
8979        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8980                != PackageManager.PERMISSION_GRANTED) {
8981            throw new SecurityException("Requires permission "
8982                    + android.Manifest.permission.STOP_APP_SWITCHES);
8983        }
8984
8985        synchronized(this) {
8986            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8987                    + APP_SWITCH_DELAY_TIME;
8988            mDidAppSwitch = false;
8989            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8990            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8991            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8992        }
8993    }
8994
8995    public void resumeAppSwitches() {
8996        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8997                != PackageManager.PERMISSION_GRANTED) {
8998            throw new SecurityException("Requires permission "
8999                    + android.Manifest.permission.STOP_APP_SWITCHES);
9000        }
9001
9002        synchronized(this) {
9003            // Note that we don't execute any pending app switches... we will
9004            // let those wait until either the timeout, or the next start
9005            // activity request.
9006            mAppSwitchesAllowedTime = 0;
9007        }
9008    }
9009
9010    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9011            String name) {
9012        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9013            return true;
9014        }
9015
9016        final int perm = checkComponentPermission(
9017                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9018                callingUid, -1, true);
9019        if (perm == PackageManager.PERMISSION_GRANTED) {
9020            return true;
9021        }
9022
9023        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9024        return false;
9025    }
9026
9027    public void setDebugApp(String packageName, boolean waitForDebugger,
9028            boolean persistent) {
9029        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9030                "setDebugApp()");
9031
9032        long ident = Binder.clearCallingIdentity();
9033        try {
9034            // Note that this is not really thread safe if there are multiple
9035            // callers into it at the same time, but that's not a situation we
9036            // care about.
9037            if (persistent) {
9038                final ContentResolver resolver = mContext.getContentResolver();
9039                Settings.Global.putString(
9040                    resolver, Settings.Global.DEBUG_APP,
9041                    packageName);
9042                Settings.Global.putInt(
9043                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9044                    waitForDebugger ? 1 : 0);
9045            }
9046
9047            synchronized (this) {
9048                if (!persistent) {
9049                    mOrigDebugApp = mDebugApp;
9050                    mOrigWaitForDebugger = mWaitForDebugger;
9051                }
9052                mDebugApp = packageName;
9053                mWaitForDebugger = waitForDebugger;
9054                mDebugTransient = !persistent;
9055                if (packageName != null) {
9056                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9057                            false, UserHandle.USER_ALL, "set debug app");
9058                }
9059            }
9060        } finally {
9061            Binder.restoreCallingIdentity(ident);
9062        }
9063    }
9064
9065    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9066        synchronized (this) {
9067            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9068            if (!isDebuggable) {
9069                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9070                    throw new SecurityException("Process not debuggable: " + app.packageName);
9071                }
9072            }
9073
9074            mOpenGlTraceApp = processName;
9075        }
9076    }
9077
9078    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9079            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9080        synchronized (this) {
9081            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9082            if (!isDebuggable) {
9083                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9084                    throw new SecurityException("Process not debuggable: " + app.packageName);
9085                }
9086            }
9087            mProfileApp = processName;
9088            mProfileFile = profileFile;
9089            if (mProfileFd != null) {
9090                try {
9091                    mProfileFd.close();
9092                } catch (IOException e) {
9093                }
9094                mProfileFd = null;
9095            }
9096            mProfileFd = profileFd;
9097            mProfileType = 0;
9098            mAutoStopProfiler = autoStopProfiler;
9099        }
9100    }
9101
9102    @Override
9103    public void setAlwaysFinish(boolean enabled) {
9104        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9105                "setAlwaysFinish()");
9106
9107        Settings.Global.putInt(
9108                mContext.getContentResolver(),
9109                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9110
9111        synchronized (this) {
9112            mAlwaysFinishActivities = enabled;
9113        }
9114    }
9115
9116    @Override
9117    public void setActivityController(IActivityController controller) {
9118        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9119                "setActivityController()");
9120        synchronized (this) {
9121            mController = controller;
9122            Watchdog.getInstance().setActivityController(controller);
9123        }
9124    }
9125
9126    @Override
9127    public void setUserIsMonkey(boolean userIsMonkey) {
9128        synchronized (this) {
9129            synchronized (mPidsSelfLocked) {
9130                final int callingPid = Binder.getCallingPid();
9131                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9132                if (precessRecord == null) {
9133                    throw new SecurityException("Unknown process: " + callingPid);
9134                }
9135                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9136                    throw new SecurityException("Only an instrumentation process "
9137                            + "with a UiAutomation can call setUserIsMonkey");
9138                }
9139            }
9140            mUserIsMonkey = userIsMonkey;
9141        }
9142    }
9143
9144    @Override
9145    public boolean isUserAMonkey() {
9146        synchronized (this) {
9147            // If there is a controller also implies the user is a monkey.
9148            return (mUserIsMonkey || mController != null);
9149        }
9150    }
9151
9152    public void requestBugReport() {
9153        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9154        SystemProperties.set("ctl.start", "bugreport");
9155    }
9156
9157    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9158        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9159    }
9160
9161    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9162        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9163            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9164        }
9165        return KEY_DISPATCHING_TIMEOUT;
9166    }
9167
9168    @Override
9169    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9170        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9171                != PackageManager.PERMISSION_GRANTED) {
9172            throw new SecurityException("Requires permission "
9173                    + android.Manifest.permission.FILTER_EVENTS);
9174        }
9175        ProcessRecord proc;
9176        long timeout;
9177        synchronized (this) {
9178            synchronized (mPidsSelfLocked) {
9179                proc = mPidsSelfLocked.get(pid);
9180            }
9181            timeout = getInputDispatchingTimeoutLocked(proc);
9182        }
9183
9184        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9185            return -1;
9186        }
9187
9188        return timeout;
9189    }
9190
9191    /**
9192     * Handle input dispatching timeouts.
9193     * Returns whether input dispatching should be aborted or not.
9194     */
9195    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9196            final ActivityRecord activity, final ActivityRecord parent,
9197            final boolean aboveSystem, String reason) {
9198        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9199                != PackageManager.PERMISSION_GRANTED) {
9200            throw new SecurityException("Requires permission "
9201                    + android.Manifest.permission.FILTER_EVENTS);
9202        }
9203
9204        final String annotation;
9205        if (reason == null) {
9206            annotation = "Input dispatching timed out";
9207        } else {
9208            annotation = "Input dispatching timed out (" + reason + ")";
9209        }
9210
9211        if (proc != null) {
9212            synchronized (this) {
9213                if (proc.debugging) {
9214                    return false;
9215                }
9216
9217                if (mDidDexOpt) {
9218                    // Give more time since we were dexopting.
9219                    mDidDexOpt = false;
9220                    return false;
9221                }
9222
9223                if (proc.instrumentationClass != null) {
9224                    Bundle info = new Bundle();
9225                    info.putString("shortMsg", "keyDispatchingTimedOut");
9226                    info.putString("longMsg", annotation);
9227                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9228                    return true;
9229                }
9230            }
9231            mHandler.post(new Runnable() {
9232                @Override
9233                public void run() {
9234                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9235                }
9236            });
9237        }
9238
9239        return true;
9240    }
9241
9242    public Bundle getAssistContextExtras(int requestType) {
9243        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9244                "getAssistContextExtras()");
9245        PendingAssistExtras pae;
9246        Bundle extras = new Bundle();
9247        synchronized (this) {
9248            ActivityRecord activity = getFocusedStack().mResumedActivity;
9249            if (activity == null) {
9250                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9251                return null;
9252            }
9253            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9254            if (activity.app == null || activity.app.thread == null) {
9255                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9256                return extras;
9257            }
9258            if (activity.app.pid == Binder.getCallingPid()) {
9259                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9260                return extras;
9261            }
9262            pae = new PendingAssistExtras(activity);
9263            try {
9264                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9265                        requestType);
9266                mPendingAssistExtras.add(pae);
9267                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9268            } catch (RemoteException e) {
9269                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9270                return extras;
9271            }
9272        }
9273        synchronized (pae) {
9274            while (!pae.haveResult) {
9275                try {
9276                    pae.wait();
9277                } catch (InterruptedException e) {
9278                }
9279            }
9280            if (pae.result != null) {
9281                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9282            }
9283        }
9284        synchronized (this) {
9285            mPendingAssistExtras.remove(pae);
9286            mHandler.removeCallbacks(pae);
9287        }
9288        return extras;
9289    }
9290
9291    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9292        PendingAssistExtras pae = (PendingAssistExtras)token;
9293        synchronized (pae) {
9294            pae.result = extras;
9295            pae.haveResult = true;
9296            pae.notifyAll();
9297        }
9298    }
9299
9300    public void registerProcessObserver(IProcessObserver observer) {
9301        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9302                "registerProcessObserver()");
9303        synchronized (this) {
9304            mProcessObservers.register(observer);
9305        }
9306    }
9307
9308    @Override
9309    public void unregisterProcessObserver(IProcessObserver observer) {
9310        synchronized (this) {
9311            mProcessObservers.unregister(observer);
9312        }
9313    }
9314
9315    @Override
9316    public boolean convertFromTranslucent(IBinder token) {
9317        final long origId = Binder.clearCallingIdentity();
9318        try {
9319            synchronized (this) {
9320                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9321                if (r == null) {
9322                    return false;
9323                }
9324                if (r.changeWindowTranslucency(true)) {
9325                    mWindowManager.setAppFullscreen(token, true);
9326                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9327                    return true;
9328                }
9329                return false;
9330            }
9331        } finally {
9332            Binder.restoreCallingIdentity(origId);
9333        }
9334    }
9335
9336    @Override
9337    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9338        final long origId = Binder.clearCallingIdentity();
9339        try {
9340            synchronized (this) {
9341                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9342                if (r == null) {
9343                    return false;
9344                }
9345                if (r.changeWindowTranslucency(false)) {
9346                    r.task.stack.convertToTranslucent(r, options);
9347                    mWindowManager.setAppFullscreen(token, false);
9348                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9349                    return true;
9350                }
9351                return false;
9352            }
9353        } finally {
9354            Binder.restoreCallingIdentity(origId);
9355        }
9356    }
9357
9358    @Override
9359    public ActivityOptions getActivityOptions(IBinder token) {
9360        final long origId = Binder.clearCallingIdentity();
9361        try {
9362            synchronized (this) {
9363                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9364                if (r != null) {
9365                    final ActivityOptions activityOptions = r.pendingOptions;
9366                    r.pendingOptions = null;
9367                    return activityOptions;
9368                }
9369                return null;
9370            }
9371        } finally {
9372            Binder.restoreCallingIdentity(origId);
9373        }
9374    }
9375
9376    @Override
9377    public void setImmersive(IBinder token, boolean immersive) {
9378        synchronized(this) {
9379            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9380            if (r == null) {
9381                throw new IllegalArgumentException();
9382            }
9383            r.immersive = immersive;
9384
9385            // update associated state if we're frontmost
9386            if (r == mFocusedActivity) {
9387                if (DEBUG_IMMERSIVE) {
9388                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9389                }
9390                applyUpdateLockStateLocked(r);
9391            }
9392        }
9393    }
9394
9395    @Override
9396    public boolean isImmersive(IBinder token) {
9397        synchronized (this) {
9398            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9399            if (r == null) {
9400                throw new IllegalArgumentException();
9401            }
9402            return r.immersive;
9403        }
9404    }
9405
9406    public boolean isTopActivityImmersive() {
9407        enforceNotIsolatedCaller("startActivity");
9408        synchronized (this) {
9409            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9410            return (r != null) ? r.immersive : false;
9411        }
9412    }
9413
9414    public final void enterSafeMode() {
9415        synchronized(this) {
9416            // It only makes sense to do this before the system is ready
9417            // and started launching other packages.
9418            if (!mSystemReady) {
9419                try {
9420                    AppGlobals.getPackageManager().enterSafeMode();
9421                } catch (RemoteException e) {
9422                }
9423            }
9424
9425            mSafeMode = true;
9426        }
9427    }
9428
9429    public final void showSafeModeOverlay() {
9430        View v = LayoutInflater.from(mContext).inflate(
9431                com.android.internal.R.layout.safe_mode, null);
9432        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9433        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9434        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9435        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9436        lp.gravity = Gravity.BOTTOM | Gravity.START;
9437        lp.format = v.getBackground().getOpacity();
9438        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9439                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9440        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9441        ((WindowManager)mContext.getSystemService(
9442                Context.WINDOW_SERVICE)).addView(v, lp);
9443    }
9444
9445    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9446        if (!(sender instanceof PendingIntentRecord)) {
9447            return;
9448        }
9449        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9450        synchronized (stats) {
9451            if (mBatteryStatsService.isOnBattery()) {
9452                mBatteryStatsService.enforceCallingPermission();
9453                PendingIntentRecord rec = (PendingIntentRecord)sender;
9454                int MY_UID = Binder.getCallingUid();
9455                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9456                BatteryStatsImpl.Uid.Pkg pkg =
9457                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9458                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9459                pkg.incWakeupsLocked();
9460            }
9461        }
9462    }
9463
9464    public boolean killPids(int[] pids, String pReason, boolean secure) {
9465        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9466            throw new SecurityException("killPids only available to the system");
9467        }
9468        String reason = (pReason == null) ? "Unknown" : pReason;
9469        // XXX Note: don't acquire main activity lock here, because the window
9470        // manager calls in with its locks held.
9471
9472        boolean killed = false;
9473        synchronized (mPidsSelfLocked) {
9474            int[] types = new int[pids.length];
9475            int worstType = 0;
9476            for (int i=0; i<pids.length; i++) {
9477                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9478                if (proc != null) {
9479                    int type = proc.setAdj;
9480                    types[i] = type;
9481                    if (type > worstType) {
9482                        worstType = type;
9483                    }
9484                }
9485            }
9486
9487            // If the worst oom_adj is somewhere in the cached proc LRU range,
9488            // then constrain it so we will kill all cached procs.
9489            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9490                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9491                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9492            }
9493
9494            // If this is not a secure call, don't let it kill processes that
9495            // are important.
9496            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9497                worstType = ProcessList.SERVICE_ADJ;
9498            }
9499
9500            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9501            for (int i=0; i<pids.length; i++) {
9502                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9503                if (proc == null) {
9504                    continue;
9505                }
9506                int adj = proc.setAdj;
9507                if (adj >= worstType && !proc.killedByAm) {
9508                    killUnneededProcessLocked(proc, reason);
9509                    killed = true;
9510                }
9511            }
9512        }
9513        return killed;
9514    }
9515
9516    @Override
9517    public void killUid(int uid, String reason) {
9518        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9519            throw new SecurityException("killUid only available to the system");
9520        }
9521        synchronized (this) {
9522            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9523                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9524                    reason != null ? reason : "kill uid");
9525        }
9526    }
9527
9528    @Override
9529    public boolean killProcessesBelowForeground(String reason) {
9530        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9531            throw new SecurityException("killProcessesBelowForeground() only available to system");
9532        }
9533
9534        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9535    }
9536
9537    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9538        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9539            throw new SecurityException("killProcessesBelowAdj() only available to system");
9540        }
9541
9542        boolean killed = false;
9543        synchronized (mPidsSelfLocked) {
9544            final int size = mPidsSelfLocked.size();
9545            for (int i = 0; i < size; i++) {
9546                final int pid = mPidsSelfLocked.keyAt(i);
9547                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9548                if (proc == null) continue;
9549
9550                final int adj = proc.setAdj;
9551                if (adj > belowAdj && !proc.killedByAm) {
9552                    killUnneededProcessLocked(proc, reason);
9553                    killed = true;
9554                }
9555            }
9556        }
9557        return killed;
9558    }
9559
9560    @Override
9561    public void hang(final IBinder who, boolean allowRestart) {
9562        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9563                != PackageManager.PERMISSION_GRANTED) {
9564            throw new SecurityException("Requires permission "
9565                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9566        }
9567
9568        final IBinder.DeathRecipient death = new DeathRecipient() {
9569            @Override
9570            public void binderDied() {
9571                synchronized (this) {
9572                    notifyAll();
9573                }
9574            }
9575        };
9576
9577        try {
9578            who.linkToDeath(death, 0);
9579        } catch (RemoteException e) {
9580            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9581            return;
9582        }
9583
9584        synchronized (this) {
9585            Watchdog.getInstance().setAllowRestart(allowRestart);
9586            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9587            synchronized (death) {
9588                while (who.isBinderAlive()) {
9589                    try {
9590                        death.wait();
9591                    } catch (InterruptedException e) {
9592                    }
9593                }
9594            }
9595            Watchdog.getInstance().setAllowRestart(true);
9596        }
9597    }
9598
9599    @Override
9600    public void restart() {
9601        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9602                != PackageManager.PERMISSION_GRANTED) {
9603            throw new SecurityException("Requires permission "
9604                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9605        }
9606
9607        Log.i(TAG, "Sending shutdown broadcast...");
9608
9609        BroadcastReceiver br = new BroadcastReceiver() {
9610            @Override public void onReceive(Context context, Intent intent) {
9611                // Now the broadcast is done, finish up the low-level shutdown.
9612                Log.i(TAG, "Shutting down activity manager...");
9613                shutdown(10000);
9614                Log.i(TAG, "Shutdown complete, restarting!");
9615                Process.killProcess(Process.myPid());
9616                System.exit(10);
9617            }
9618        };
9619
9620        // First send the high-level shut down broadcast.
9621        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9622        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9623        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9624        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9625        mContext.sendOrderedBroadcastAsUser(intent,
9626                UserHandle.ALL, null, br, mHandler, 0, null, null);
9627        */
9628        br.onReceive(mContext, intent);
9629    }
9630
9631    private long getLowRamTimeSinceIdle(long now) {
9632        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9633    }
9634
9635    @Override
9636    public void performIdleMaintenance() {
9637        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9638                != PackageManager.PERMISSION_GRANTED) {
9639            throw new SecurityException("Requires permission "
9640                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9641        }
9642
9643        synchronized (this) {
9644            final long now = SystemClock.uptimeMillis();
9645            final long timeSinceLastIdle = now - mLastIdleTime;
9646            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9647            mLastIdleTime = now;
9648            mLowRamTimeSinceLastIdle = 0;
9649            if (mLowRamStartTime != 0) {
9650                mLowRamStartTime = now;
9651            }
9652
9653            StringBuilder sb = new StringBuilder(128);
9654            sb.append("Idle maintenance over ");
9655            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9656            sb.append(" low RAM for ");
9657            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9658            Slog.i(TAG, sb.toString());
9659
9660            // If at least 1/3 of our time since the last idle period has been spent
9661            // with RAM low, then we want to kill processes.
9662            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9663
9664            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9665                ProcessRecord proc = mLruProcesses.get(i);
9666                if (proc.notCachedSinceIdle) {
9667                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9668                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9669                        if (doKilling && proc.initialIdlePss != 0
9670                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9671                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9672                                    + " from " + proc.initialIdlePss + ")");
9673                        }
9674                    }
9675                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9676                    proc.notCachedSinceIdle = true;
9677                    proc.initialIdlePss = 0;
9678                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9679                            isSleeping(), now);
9680                }
9681            }
9682
9683            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9684            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9685        }
9686    }
9687
9688    private void retrieveSettings() {
9689        final ContentResolver resolver = mContext.getContentResolver();
9690        String debugApp = Settings.Global.getString(
9691            resolver, Settings.Global.DEBUG_APP);
9692        boolean waitForDebugger = Settings.Global.getInt(
9693            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9694        boolean alwaysFinishActivities = Settings.Global.getInt(
9695            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9696        boolean forceRtl = Settings.Global.getInt(
9697                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9698        // Transfer any global setting for forcing RTL layout, into a System Property
9699        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9700
9701        Configuration configuration = new Configuration();
9702        Settings.System.getConfiguration(resolver, configuration);
9703        if (forceRtl) {
9704            // This will take care of setting the correct layout direction flags
9705            configuration.setLayoutDirection(configuration.locale);
9706        }
9707
9708        synchronized (this) {
9709            mDebugApp = mOrigDebugApp = debugApp;
9710            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9711            mAlwaysFinishActivities = alwaysFinishActivities;
9712            // This happens before any activities are started, so we can
9713            // change mConfiguration in-place.
9714            updateConfigurationLocked(configuration, null, false, true);
9715            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9716        }
9717    }
9718
9719    public boolean testIsSystemReady() {
9720        // no need to synchronize(this) just to read & return the value
9721        return mSystemReady;
9722    }
9723
9724    private static File getCalledPreBootReceiversFile() {
9725        File dataDir = Environment.getDataDirectory();
9726        File systemDir = new File(dataDir, "system");
9727        File fname = new File(systemDir, "called_pre_boots.dat");
9728        return fname;
9729    }
9730
9731    static final int LAST_DONE_VERSION = 10000;
9732
9733    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9734        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9735        File file = getCalledPreBootReceiversFile();
9736        FileInputStream fis = null;
9737        try {
9738            fis = new FileInputStream(file);
9739            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9740            int fvers = dis.readInt();
9741            if (fvers == LAST_DONE_VERSION) {
9742                String vers = dis.readUTF();
9743                String codename = dis.readUTF();
9744                String build = dis.readUTF();
9745                if (android.os.Build.VERSION.RELEASE.equals(vers)
9746                        && android.os.Build.VERSION.CODENAME.equals(codename)
9747                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9748                    int num = dis.readInt();
9749                    while (num > 0) {
9750                        num--;
9751                        String pkg = dis.readUTF();
9752                        String cls = dis.readUTF();
9753                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9754                    }
9755                }
9756            }
9757        } catch (FileNotFoundException e) {
9758        } catch (IOException e) {
9759            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9760        } finally {
9761            if (fis != null) {
9762                try {
9763                    fis.close();
9764                } catch (IOException e) {
9765                }
9766            }
9767        }
9768        return lastDoneReceivers;
9769    }
9770
9771    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9772        File file = getCalledPreBootReceiversFile();
9773        FileOutputStream fos = null;
9774        DataOutputStream dos = null;
9775        try {
9776            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9777            fos = new FileOutputStream(file);
9778            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9779            dos.writeInt(LAST_DONE_VERSION);
9780            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9781            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9782            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9783            dos.writeInt(list.size());
9784            for (int i=0; i<list.size(); i++) {
9785                dos.writeUTF(list.get(i).getPackageName());
9786                dos.writeUTF(list.get(i).getClassName());
9787            }
9788        } catch (IOException e) {
9789            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9790            file.delete();
9791        } finally {
9792            FileUtils.sync(fos);
9793            if (dos != null) {
9794                try {
9795                    dos.close();
9796                } catch (IOException e) {
9797                    // TODO Auto-generated catch block
9798                    e.printStackTrace();
9799                }
9800            }
9801        }
9802    }
9803
9804    public void systemReady(final Runnable goingCallback) {
9805        synchronized(this) {
9806            if (mSystemReady) {
9807                if (goingCallback != null) goingCallback.run();
9808                return;
9809            }
9810
9811            if (mRecentTasks == null) {
9812                mRecentTasks = mTaskPersister.restoreTasksLocked();
9813                if (!mRecentTasks.isEmpty()) {
9814                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
9815                }
9816                mTaskPersister.startPersisting();
9817            }
9818
9819            // Check to see if there are any update receivers to run.
9820            if (!mDidUpdate) {
9821                if (mWaitingUpdate) {
9822                    return;
9823                }
9824                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9825                List<ResolveInfo> ris = null;
9826                try {
9827                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9828                            intent, null, 0, 0);
9829                } catch (RemoteException e) {
9830                }
9831                if (ris != null) {
9832                    for (int i=ris.size()-1; i>=0; i--) {
9833                        if ((ris.get(i).activityInfo.applicationInfo.flags
9834                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9835                            ris.remove(i);
9836                        }
9837                    }
9838                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9839
9840                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9841
9842                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9843                    for (int i=0; i<ris.size(); i++) {
9844                        ActivityInfo ai = ris.get(i).activityInfo;
9845                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9846                        if (lastDoneReceivers.contains(comp)) {
9847                            // We already did the pre boot receiver for this app with the current
9848                            // platform version, so don't do it again...
9849                            ris.remove(i);
9850                            i--;
9851                            // ...however, do keep it as one that has been done, so we don't
9852                            // forget about it when rewriting the file of last done receivers.
9853                            doneReceivers.add(comp);
9854                        }
9855                    }
9856
9857                    final int[] users = getUsersLocked();
9858                    for (int i=0; i<ris.size(); i++) {
9859                        ActivityInfo ai = ris.get(i).activityInfo;
9860                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9861                        doneReceivers.add(comp);
9862                        intent.setComponent(comp);
9863                        for (int j=0; j<users.length; j++) {
9864                            IIntentReceiver finisher = null;
9865                            if (i == ris.size()-1 && j == users.length-1) {
9866                                finisher = new IIntentReceiver.Stub() {
9867                                    public void performReceive(Intent intent, int resultCode,
9868                                            String data, Bundle extras, boolean ordered,
9869                                            boolean sticky, int sendingUser) {
9870                                        // The raw IIntentReceiver interface is called
9871                                        // with the AM lock held, so redispatch to
9872                                        // execute our code without the lock.
9873                                        mHandler.post(new Runnable() {
9874                                            public void run() {
9875                                                synchronized (ActivityManagerService.this) {
9876                                                    mDidUpdate = true;
9877                                                }
9878                                                writeLastDonePreBootReceivers(doneReceivers);
9879                                                showBootMessage(mContext.getText(
9880                                                        R.string.android_upgrading_complete),
9881                                                        false);
9882                                                systemReady(goingCallback);
9883                                            }
9884                                        });
9885                                    }
9886                                };
9887                            }
9888                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9889                                    + " for user " + users[j]);
9890                            broadcastIntentLocked(null, null, intent, null, finisher,
9891                                    0, null, null, null, AppOpsManager.OP_NONE,
9892                                    true, false, MY_PID, Process.SYSTEM_UID,
9893                                    users[j]);
9894                            if (finisher != null) {
9895                                mWaitingUpdate = true;
9896                            }
9897                        }
9898                    }
9899                }
9900                if (mWaitingUpdate) {
9901                    return;
9902                }
9903                mDidUpdate = true;
9904            }
9905
9906            mAppOpsService.systemReady();
9907            mUsageStatsService.systemReady();
9908            mSystemReady = true;
9909        }
9910
9911        ArrayList<ProcessRecord> procsToKill = null;
9912        synchronized(mPidsSelfLocked) {
9913            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9914                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9915                if (!isAllowedWhileBooting(proc.info)){
9916                    if (procsToKill == null) {
9917                        procsToKill = new ArrayList<ProcessRecord>();
9918                    }
9919                    procsToKill.add(proc);
9920                }
9921            }
9922        }
9923
9924        synchronized(this) {
9925            if (procsToKill != null) {
9926                for (int i=procsToKill.size()-1; i>=0; i--) {
9927                    ProcessRecord proc = procsToKill.get(i);
9928                    Slog.i(TAG, "Removing system update proc: " + proc);
9929                    removeProcessLocked(proc, true, false, "system update done");
9930                }
9931            }
9932
9933            // Now that we have cleaned up any update processes, we
9934            // are ready to start launching real processes and know that
9935            // we won't trample on them any more.
9936            mProcessesReady = true;
9937        }
9938
9939        Slog.i(TAG, "System now ready");
9940        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9941            SystemClock.uptimeMillis());
9942
9943        synchronized(this) {
9944            // Make sure we have no pre-ready processes sitting around.
9945
9946            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9947                ResolveInfo ri = mContext.getPackageManager()
9948                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9949                                STOCK_PM_FLAGS);
9950                CharSequence errorMsg = null;
9951                if (ri != null) {
9952                    ActivityInfo ai = ri.activityInfo;
9953                    ApplicationInfo app = ai.applicationInfo;
9954                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9955                        mTopAction = Intent.ACTION_FACTORY_TEST;
9956                        mTopData = null;
9957                        mTopComponent = new ComponentName(app.packageName,
9958                                ai.name);
9959                    } else {
9960                        errorMsg = mContext.getResources().getText(
9961                                com.android.internal.R.string.factorytest_not_system);
9962                    }
9963                } else {
9964                    errorMsg = mContext.getResources().getText(
9965                            com.android.internal.R.string.factorytest_no_action);
9966                }
9967                if (errorMsg != null) {
9968                    mTopAction = null;
9969                    mTopData = null;
9970                    mTopComponent = null;
9971                    Message msg = Message.obtain();
9972                    msg.what = SHOW_FACTORY_ERROR_MSG;
9973                    msg.getData().putCharSequence("msg", errorMsg);
9974                    mHandler.sendMessage(msg);
9975                }
9976            }
9977        }
9978
9979        retrieveSettings();
9980
9981        synchronized (this) {
9982            readGrantedUriPermissionsLocked();
9983        }
9984
9985        if (goingCallback != null) goingCallback.run();
9986
9987        mSystemServiceManager.startUser(mCurrentUserId);
9988
9989        synchronized (this) {
9990            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9991                try {
9992                    List apps = AppGlobals.getPackageManager().
9993                        getPersistentApplications(STOCK_PM_FLAGS);
9994                    if (apps != null) {
9995                        int N = apps.size();
9996                        int i;
9997                        for (i=0; i<N; i++) {
9998                            ApplicationInfo info
9999                                = (ApplicationInfo)apps.get(i);
10000                            if (info != null &&
10001                                    !info.packageName.equals("android")) {
10002                                addAppLocked(info, false, null /* ABI override */);
10003                            }
10004                        }
10005                    }
10006                } catch (RemoteException ex) {
10007                    // pm is in same process, this will never happen.
10008                }
10009            }
10010
10011            // Start up initial activity.
10012            mBooting = true;
10013
10014            try {
10015                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10016                    Message msg = Message.obtain();
10017                    msg.what = SHOW_UID_ERROR_MSG;
10018                    mHandler.sendMessage(msg);
10019                }
10020            } catch (RemoteException e) {
10021            }
10022
10023            long ident = Binder.clearCallingIdentity();
10024            try {
10025                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10026                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10027                        | Intent.FLAG_RECEIVER_FOREGROUND);
10028                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10029                broadcastIntentLocked(null, null, intent,
10030                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10031                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10032                intent = new Intent(Intent.ACTION_USER_STARTING);
10033                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10034                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10035                broadcastIntentLocked(null, null, intent,
10036                        null, new IIntentReceiver.Stub() {
10037                            @Override
10038                            public void performReceive(Intent intent, int resultCode, String data,
10039                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10040                                    throws RemoteException {
10041                            }
10042                        }, 0, null, null,
10043                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10044                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10045            } catch (Throwable t) {
10046                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10047            } finally {
10048                Binder.restoreCallingIdentity(ident);
10049            }
10050            mStackSupervisor.resumeTopActivitiesLocked();
10051            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10052        }
10053    }
10054
10055    private boolean makeAppCrashingLocked(ProcessRecord app,
10056            String shortMsg, String longMsg, String stackTrace) {
10057        app.crashing = true;
10058        app.crashingReport = generateProcessError(app,
10059                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10060        startAppProblemLocked(app);
10061        app.stopFreezingAllLocked();
10062        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10063    }
10064
10065    private void makeAppNotRespondingLocked(ProcessRecord app,
10066            String activity, String shortMsg, String longMsg) {
10067        app.notResponding = true;
10068        app.notRespondingReport = generateProcessError(app,
10069                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10070                activity, shortMsg, longMsg, null);
10071        startAppProblemLocked(app);
10072        app.stopFreezingAllLocked();
10073    }
10074
10075    /**
10076     * Generate a process error record, suitable for attachment to a ProcessRecord.
10077     *
10078     * @param app The ProcessRecord in which the error occurred.
10079     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10080     *                      ActivityManager.AppErrorStateInfo
10081     * @param activity The activity associated with the crash, if known.
10082     * @param shortMsg Short message describing the crash.
10083     * @param longMsg Long message describing the crash.
10084     * @param stackTrace Full crash stack trace, may be null.
10085     *
10086     * @return Returns a fully-formed AppErrorStateInfo record.
10087     */
10088    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10089            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10090        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10091
10092        report.condition = condition;
10093        report.processName = app.processName;
10094        report.pid = app.pid;
10095        report.uid = app.info.uid;
10096        report.tag = activity;
10097        report.shortMsg = shortMsg;
10098        report.longMsg = longMsg;
10099        report.stackTrace = stackTrace;
10100
10101        return report;
10102    }
10103
10104    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10105        synchronized (this) {
10106            app.crashing = false;
10107            app.crashingReport = null;
10108            app.notResponding = false;
10109            app.notRespondingReport = null;
10110            if (app.anrDialog == fromDialog) {
10111                app.anrDialog = null;
10112            }
10113            if (app.waitDialog == fromDialog) {
10114                app.waitDialog = null;
10115            }
10116            if (app.pid > 0 && app.pid != MY_PID) {
10117                handleAppCrashLocked(app, null, null, null);
10118                killUnneededProcessLocked(app, "user request after error");
10119            }
10120        }
10121    }
10122
10123    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10124            String stackTrace) {
10125        long now = SystemClock.uptimeMillis();
10126
10127        Long crashTime;
10128        if (!app.isolated) {
10129            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10130        } else {
10131            crashTime = null;
10132        }
10133        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10134            // This process loses!
10135            Slog.w(TAG, "Process " + app.info.processName
10136                    + " has crashed too many times: killing!");
10137            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10138                    app.userId, app.info.processName, app.uid);
10139            mStackSupervisor.handleAppCrashLocked(app);
10140            if (!app.persistent) {
10141                // We don't want to start this process again until the user
10142                // explicitly does so...  but for persistent process, we really
10143                // need to keep it running.  If a persistent process is actually
10144                // repeatedly crashing, then badness for everyone.
10145                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10146                        app.info.processName);
10147                if (!app.isolated) {
10148                    // XXX We don't have a way to mark isolated processes
10149                    // as bad, since they don't have a peristent identity.
10150                    mBadProcesses.put(app.info.processName, app.uid,
10151                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10152                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10153                }
10154                app.bad = true;
10155                app.removed = true;
10156                // Don't let services in this process be restarted and potentially
10157                // annoy the user repeatedly.  Unless it is persistent, since those
10158                // processes run critical code.
10159                removeProcessLocked(app, false, false, "crash");
10160                mStackSupervisor.resumeTopActivitiesLocked();
10161                return false;
10162            }
10163            mStackSupervisor.resumeTopActivitiesLocked();
10164        } else {
10165            mStackSupervisor.finishTopRunningActivityLocked(app);
10166        }
10167
10168        // Bump up the crash count of any services currently running in the proc.
10169        for (int i=app.services.size()-1; i>=0; i--) {
10170            // Any services running in the application need to be placed
10171            // back in the pending list.
10172            ServiceRecord sr = app.services.valueAt(i);
10173            sr.crashCount++;
10174        }
10175
10176        // If the crashing process is what we consider to be the "home process" and it has been
10177        // replaced by a third-party app, clear the package preferred activities from packages
10178        // with a home activity running in the process to prevent a repeatedly crashing app
10179        // from blocking the user to manually clear the list.
10180        final ArrayList<ActivityRecord> activities = app.activities;
10181        if (app == mHomeProcess && activities.size() > 0
10182                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10183            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10184                final ActivityRecord r = activities.get(activityNdx);
10185                if (r.isHomeActivity()) {
10186                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10187                    try {
10188                        ActivityThread.getPackageManager()
10189                                .clearPackagePreferredActivities(r.packageName);
10190                    } catch (RemoteException c) {
10191                        // pm is in same process, this will never happen.
10192                    }
10193                }
10194            }
10195        }
10196
10197        if (!app.isolated) {
10198            // XXX Can't keep track of crash times for isolated processes,
10199            // because they don't have a perisistent identity.
10200            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10201        }
10202
10203        return true;
10204    }
10205
10206    void startAppProblemLocked(ProcessRecord app) {
10207        if (app.userId == mCurrentUserId) {
10208            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10209                    mContext, app.info.packageName, app.info.flags);
10210        } else {
10211            // If this app is not running under the current user, then we
10212            // can't give it a report button because that would require
10213            // launching the report UI under a different user.
10214            app.errorReportReceiver = null;
10215        }
10216        skipCurrentReceiverLocked(app);
10217    }
10218
10219    void skipCurrentReceiverLocked(ProcessRecord app) {
10220        for (BroadcastQueue queue : mBroadcastQueues) {
10221            queue.skipCurrentReceiverLocked(app);
10222        }
10223    }
10224
10225    /**
10226     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10227     * The application process will exit immediately after this call returns.
10228     * @param app object of the crashing app, null for the system server
10229     * @param crashInfo describing the exception
10230     */
10231    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10232        ProcessRecord r = findAppProcess(app, "Crash");
10233        final String processName = app == null ? "system_server"
10234                : (r == null ? "unknown" : r.processName);
10235
10236        handleApplicationCrashInner("crash", r, processName, crashInfo);
10237    }
10238
10239    /* Native crash reporting uses this inner version because it needs to be somewhat
10240     * decoupled from the AM-managed cleanup lifecycle
10241     */
10242    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10243            ApplicationErrorReport.CrashInfo crashInfo) {
10244        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10245                UserHandle.getUserId(Binder.getCallingUid()), processName,
10246                r == null ? -1 : r.info.flags,
10247                crashInfo.exceptionClassName,
10248                crashInfo.exceptionMessage,
10249                crashInfo.throwFileName,
10250                crashInfo.throwLineNumber);
10251
10252        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10253
10254        crashApplication(r, crashInfo);
10255    }
10256
10257    public void handleApplicationStrictModeViolation(
10258            IBinder app,
10259            int violationMask,
10260            StrictMode.ViolationInfo info) {
10261        ProcessRecord r = findAppProcess(app, "StrictMode");
10262        if (r == null) {
10263            return;
10264        }
10265
10266        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10267            Integer stackFingerprint = info.hashCode();
10268            boolean logIt = true;
10269            synchronized (mAlreadyLoggedViolatedStacks) {
10270                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10271                    logIt = false;
10272                    // TODO: sub-sample into EventLog for these, with
10273                    // the info.durationMillis?  Then we'd get
10274                    // the relative pain numbers, without logging all
10275                    // the stack traces repeatedly.  We'd want to do
10276                    // likewise in the client code, which also does
10277                    // dup suppression, before the Binder call.
10278                } else {
10279                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10280                        mAlreadyLoggedViolatedStacks.clear();
10281                    }
10282                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10283                }
10284            }
10285            if (logIt) {
10286                logStrictModeViolationToDropBox(r, info);
10287            }
10288        }
10289
10290        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10291            AppErrorResult result = new AppErrorResult();
10292            synchronized (this) {
10293                final long origId = Binder.clearCallingIdentity();
10294
10295                Message msg = Message.obtain();
10296                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10297                HashMap<String, Object> data = new HashMap<String, Object>();
10298                data.put("result", result);
10299                data.put("app", r);
10300                data.put("violationMask", violationMask);
10301                data.put("info", info);
10302                msg.obj = data;
10303                mHandler.sendMessage(msg);
10304
10305                Binder.restoreCallingIdentity(origId);
10306            }
10307            int res = result.get();
10308            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10309        }
10310    }
10311
10312    // Depending on the policy in effect, there could be a bunch of
10313    // these in quick succession so we try to batch these together to
10314    // minimize disk writes, number of dropbox entries, and maximize
10315    // compression, by having more fewer, larger records.
10316    private void logStrictModeViolationToDropBox(
10317            ProcessRecord process,
10318            StrictMode.ViolationInfo info) {
10319        if (info == null) {
10320            return;
10321        }
10322        final boolean isSystemApp = process == null ||
10323                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10324                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10325        final String processName = process == null ? "unknown" : process.processName;
10326        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10327        final DropBoxManager dbox = (DropBoxManager)
10328                mContext.getSystemService(Context.DROPBOX_SERVICE);
10329
10330        // Exit early if the dropbox isn't configured to accept this report type.
10331        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10332
10333        boolean bufferWasEmpty;
10334        boolean needsFlush;
10335        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10336        synchronized (sb) {
10337            bufferWasEmpty = sb.length() == 0;
10338            appendDropBoxProcessHeaders(process, processName, sb);
10339            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10340            sb.append("System-App: ").append(isSystemApp).append("\n");
10341            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10342            if (info.violationNumThisLoop != 0) {
10343                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10344            }
10345            if (info.numAnimationsRunning != 0) {
10346                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10347            }
10348            if (info.broadcastIntentAction != null) {
10349                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10350            }
10351            if (info.durationMillis != -1) {
10352                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10353            }
10354            if (info.numInstances != -1) {
10355                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10356            }
10357            if (info.tags != null) {
10358                for (String tag : info.tags) {
10359                    sb.append("Span-Tag: ").append(tag).append("\n");
10360                }
10361            }
10362            sb.append("\n");
10363            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10364                sb.append(info.crashInfo.stackTrace);
10365            }
10366            sb.append("\n");
10367
10368            // Only buffer up to ~64k.  Various logging bits truncate
10369            // things at 128k.
10370            needsFlush = (sb.length() > 64 * 1024);
10371        }
10372
10373        // Flush immediately if the buffer's grown too large, or this
10374        // is a non-system app.  Non-system apps are isolated with a
10375        // different tag & policy and not batched.
10376        //
10377        // Batching is useful during internal testing with
10378        // StrictMode settings turned up high.  Without batching,
10379        // thousands of separate files could be created on boot.
10380        if (!isSystemApp || needsFlush) {
10381            new Thread("Error dump: " + dropboxTag) {
10382                @Override
10383                public void run() {
10384                    String report;
10385                    synchronized (sb) {
10386                        report = sb.toString();
10387                        sb.delete(0, sb.length());
10388                        sb.trimToSize();
10389                    }
10390                    if (report.length() != 0) {
10391                        dbox.addText(dropboxTag, report);
10392                    }
10393                }
10394            }.start();
10395            return;
10396        }
10397
10398        // System app batching:
10399        if (!bufferWasEmpty) {
10400            // An existing dropbox-writing thread is outstanding, so
10401            // we don't need to start it up.  The existing thread will
10402            // catch the buffer appends we just did.
10403            return;
10404        }
10405
10406        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10407        // (After this point, we shouldn't access AMS internal data structures.)
10408        new Thread("Error dump: " + dropboxTag) {
10409            @Override
10410            public void run() {
10411                // 5 second sleep to let stacks arrive and be batched together
10412                try {
10413                    Thread.sleep(5000);  // 5 seconds
10414                } catch (InterruptedException e) {}
10415
10416                String errorReport;
10417                synchronized (mStrictModeBuffer) {
10418                    errorReport = mStrictModeBuffer.toString();
10419                    if (errorReport.length() == 0) {
10420                        return;
10421                    }
10422                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10423                    mStrictModeBuffer.trimToSize();
10424                }
10425                dbox.addText(dropboxTag, errorReport);
10426            }
10427        }.start();
10428    }
10429
10430    /**
10431     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10432     * @param app object of the crashing app, null for the system server
10433     * @param tag reported by the caller
10434     * @param crashInfo describing the context of the error
10435     * @return true if the process should exit immediately (WTF is fatal)
10436     */
10437    public boolean handleApplicationWtf(IBinder app, String tag,
10438            ApplicationErrorReport.CrashInfo crashInfo) {
10439        ProcessRecord r = findAppProcess(app, "WTF");
10440        final String processName = app == null ? "system_server"
10441                : (r == null ? "unknown" : r.processName);
10442
10443        EventLog.writeEvent(EventLogTags.AM_WTF,
10444                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10445                processName,
10446                r == null ? -1 : r.info.flags,
10447                tag, crashInfo.exceptionMessage);
10448
10449        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10450
10451        if (r != null && r.pid != Process.myPid() &&
10452                Settings.Global.getInt(mContext.getContentResolver(),
10453                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10454            crashApplication(r, crashInfo);
10455            return true;
10456        } else {
10457            return false;
10458        }
10459    }
10460
10461    /**
10462     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10463     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10464     */
10465    private ProcessRecord findAppProcess(IBinder app, String reason) {
10466        if (app == null) {
10467            return null;
10468        }
10469
10470        synchronized (this) {
10471            final int NP = mProcessNames.getMap().size();
10472            for (int ip=0; ip<NP; ip++) {
10473                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10474                final int NA = apps.size();
10475                for (int ia=0; ia<NA; ia++) {
10476                    ProcessRecord p = apps.valueAt(ia);
10477                    if (p.thread != null && p.thread.asBinder() == app) {
10478                        return p;
10479                    }
10480                }
10481            }
10482
10483            Slog.w(TAG, "Can't find mystery application for " + reason
10484                    + " from pid=" + Binder.getCallingPid()
10485                    + " uid=" + Binder.getCallingUid() + ": " + app);
10486            return null;
10487        }
10488    }
10489
10490    /**
10491     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10492     * to append various headers to the dropbox log text.
10493     */
10494    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10495            StringBuilder sb) {
10496        // Watchdog thread ends up invoking this function (with
10497        // a null ProcessRecord) to add the stack file to dropbox.
10498        // Do not acquire a lock on this (am) in such cases, as it
10499        // could cause a potential deadlock, if and when watchdog
10500        // is invoked due to unavailability of lock on am and it
10501        // would prevent watchdog from killing system_server.
10502        if (process == null) {
10503            sb.append("Process: ").append(processName).append("\n");
10504            return;
10505        }
10506        // Note: ProcessRecord 'process' is guarded by the service
10507        // instance.  (notably process.pkgList, which could otherwise change
10508        // concurrently during execution of this method)
10509        synchronized (this) {
10510            sb.append("Process: ").append(processName).append("\n");
10511            int flags = process.info.flags;
10512            IPackageManager pm = AppGlobals.getPackageManager();
10513            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10514            for (int ip=0; ip<process.pkgList.size(); ip++) {
10515                String pkg = process.pkgList.keyAt(ip);
10516                sb.append("Package: ").append(pkg);
10517                try {
10518                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10519                    if (pi != null) {
10520                        sb.append(" v").append(pi.versionCode);
10521                        if (pi.versionName != null) {
10522                            sb.append(" (").append(pi.versionName).append(")");
10523                        }
10524                    }
10525                } catch (RemoteException e) {
10526                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10527                }
10528                sb.append("\n");
10529            }
10530        }
10531    }
10532
10533    private static String processClass(ProcessRecord process) {
10534        if (process == null || process.pid == MY_PID) {
10535            return "system_server";
10536        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10537            return "system_app";
10538        } else {
10539            return "data_app";
10540        }
10541    }
10542
10543    /**
10544     * Write a description of an error (crash, WTF, ANR) to the drop box.
10545     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10546     * @param process which caused the error, null means the system server
10547     * @param activity which triggered the error, null if unknown
10548     * @param parent activity related to the error, null if unknown
10549     * @param subject line related to the error, null if absent
10550     * @param report in long form describing the error, null if absent
10551     * @param logFile to include in the report, null if none
10552     * @param crashInfo giving an application stack trace, null if absent
10553     */
10554    public void addErrorToDropBox(String eventType,
10555            ProcessRecord process, String processName, ActivityRecord activity,
10556            ActivityRecord parent, String subject,
10557            final String report, final File logFile,
10558            final ApplicationErrorReport.CrashInfo crashInfo) {
10559        // NOTE -- this must never acquire the ActivityManagerService lock,
10560        // otherwise the watchdog may be prevented from resetting the system.
10561
10562        final String dropboxTag = processClass(process) + "_" + eventType;
10563        final DropBoxManager dbox = (DropBoxManager)
10564                mContext.getSystemService(Context.DROPBOX_SERVICE);
10565
10566        // Exit early if the dropbox isn't configured to accept this report type.
10567        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10568
10569        final StringBuilder sb = new StringBuilder(1024);
10570        appendDropBoxProcessHeaders(process, processName, sb);
10571        if (activity != null) {
10572            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10573        }
10574        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10575            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10576        }
10577        if (parent != null && parent != activity) {
10578            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10579        }
10580        if (subject != null) {
10581            sb.append("Subject: ").append(subject).append("\n");
10582        }
10583        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10584        if (Debug.isDebuggerConnected()) {
10585            sb.append("Debugger: Connected\n");
10586        }
10587        sb.append("\n");
10588
10589        // Do the rest in a worker thread to avoid blocking the caller on I/O
10590        // (After this point, we shouldn't access AMS internal data structures.)
10591        Thread worker = new Thread("Error dump: " + dropboxTag) {
10592            @Override
10593            public void run() {
10594                if (report != null) {
10595                    sb.append(report);
10596                }
10597                if (logFile != null) {
10598                    try {
10599                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10600                                    "\n\n[[TRUNCATED]]"));
10601                    } catch (IOException e) {
10602                        Slog.e(TAG, "Error reading " + logFile, e);
10603                    }
10604                }
10605                if (crashInfo != null && crashInfo.stackTrace != null) {
10606                    sb.append(crashInfo.stackTrace);
10607                }
10608
10609                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10610                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10611                if (lines > 0) {
10612                    sb.append("\n");
10613
10614                    // Merge several logcat streams, and take the last N lines
10615                    InputStreamReader input = null;
10616                    try {
10617                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10618                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10619                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10620
10621                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10622                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10623                        input = new InputStreamReader(logcat.getInputStream());
10624
10625                        int num;
10626                        char[] buf = new char[8192];
10627                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10628                    } catch (IOException e) {
10629                        Slog.e(TAG, "Error running logcat", e);
10630                    } finally {
10631                        if (input != null) try { input.close(); } catch (IOException e) {}
10632                    }
10633                }
10634
10635                dbox.addText(dropboxTag, sb.toString());
10636            }
10637        };
10638
10639        if (process == null) {
10640            // If process is null, we are being called from some internal code
10641            // and may be about to die -- run this synchronously.
10642            worker.run();
10643        } else {
10644            worker.start();
10645        }
10646    }
10647
10648    /**
10649     * Bring up the "unexpected error" dialog box for a crashing app.
10650     * Deal with edge cases (intercepts from instrumented applications,
10651     * ActivityController, error intent receivers, that sort of thing).
10652     * @param r the application crashing
10653     * @param crashInfo describing the failure
10654     */
10655    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10656        long timeMillis = System.currentTimeMillis();
10657        String shortMsg = crashInfo.exceptionClassName;
10658        String longMsg = crashInfo.exceptionMessage;
10659        String stackTrace = crashInfo.stackTrace;
10660        if (shortMsg != null && longMsg != null) {
10661            longMsg = shortMsg + ": " + longMsg;
10662        } else if (shortMsg != null) {
10663            longMsg = shortMsg;
10664        }
10665
10666        AppErrorResult result = new AppErrorResult();
10667        synchronized (this) {
10668            if (mController != null) {
10669                try {
10670                    String name = r != null ? r.processName : null;
10671                    int pid = r != null ? r.pid : Binder.getCallingPid();
10672                    if (!mController.appCrashed(name, pid,
10673                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10674                        Slog.w(TAG, "Force-killing crashed app " + name
10675                                + " at watcher's request");
10676                        Process.killProcess(pid);
10677                        return;
10678                    }
10679                } catch (RemoteException e) {
10680                    mController = null;
10681                    Watchdog.getInstance().setActivityController(null);
10682                }
10683            }
10684
10685            final long origId = Binder.clearCallingIdentity();
10686
10687            // If this process is running instrumentation, finish it.
10688            if (r != null && r.instrumentationClass != null) {
10689                Slog.w(TAG, "Error in app " + r.processName
10690                      + " running instrumentation " + r.instrumentationClass + ":");
10691                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10692                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10693                Bundle info = new Bundle();
10694                info.putString("shortMsg", shortMsg);
10695                info.putString("longMsg", longMsg);
10696                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10697                Binder.restoreCallingIdentity(origId);
10698                return;
10699            }
10700
10701            // If we can't identify the process or it's already exceeded its crash quota,
10702            // quit right away without showing a crash dialog.
10703            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10704                Binder.restoreCallingIdentity(origId);
10705                return;
10706            }
10707
10708            Message msg = Message.obtain();
10709            msg.what = SHOW_ERROR_MSG;
10710            HashMap data = new HashMap();
10711            data.put("result", result);
10712            data.put("app", r);
10713            msg.obj = data;
10714            mHandler.sendMessage(msg);
10715
10716            Binder.restoreCallingIdentity(origId);
10717        }
10718
10719        int res = result.get();
10720
10721        Intent appErrorIntent = null;
10722        synchronized (this) {
10723            if (r != null && !r.isolated) {
10724                // XXX Can't keep track of crash time for isolated processes,
10725                // since they don't have a persistent identity.
10726                mProcessCrashTimes.put(r.info.processName, r.uid,
10727                        SystemClock.uptimeMillis());
10728            }
10729            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10730                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10731            }
10732        }
10733
10734        if (appErrorIntent != null) {
10735            try {
10736                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10737            } catch (ActivityNotFoundException e) {
10738                Slog.w(TAG, "bug report receiver dissappeared", e);
10739            }
10740        }
10741    }
10742
10743    Intent createAppErrorIntentLocked(ProcessRecord r,
10744            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10745        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10746        if (report == null) {
10747            return null;
10748        }
10749        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10750        result.setComponent(r.errorReportReceiver);
10751        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10752        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10753        return result;
10754    }
10755
10756    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10757            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10758        if (r.errorReportReceiver == null) {
10759            return null;
10760        }
10761
10762        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10763            return null;
10764        }
10765
10766        ApplicationErrorReport report = new ApplicationErrorReport();
10767        report.packageName = r.info.packageName;
10768        report.installerPackageName = r.errorReportReceiver.getPackageName();
10769        report.processName = r.processName;
10770        report.time = timeMillis;
10771        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10772
10773        if (r.crashing || r.forceCrashReport) {
10774            report.type = ApplicationErrorReport.TYPE_CRASH;
10775            report.crashInfo = crashInfo;
10776        } else if (r.notResponding) {
10777            report.type = ApplicationErrorReport.TYPE_ANR;
10778            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10779
10780            report.anrInfo.activity = r.notRespondingReport.tag;
10781            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10782            report.anrInfo.info = r.notRespondingReport.longMsg;
10783        }
10784
10785        return report;
10786    }
10787
10788    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10789        enforceNotIsolatedCaller("getProcessesInErrorState");
10790        // assume our apps are happy - lazy create the list
10791        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10792
10793        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10794                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10795        int userId = UserHandle.getUserId(Binder.getCallingUid());
10796
10797        synchronized (this) {
10798
10799            // iterate across all processes
10800            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10801                ProcessRecord app = mLruProcesses.get(i);
10802                if (!allUsers && app.userId != userId) {
10803                    continue;
10804                }
10805                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10806                    // This one's in trouble, so we'll generate a report for it
10807                    // crashes are higher priority (in case there's a crash *and* an anr)
10808                    ActivityManager.ProcessErrorStateInfo report = null;
10809                    if (app.crashing) {
10810                        report = app.crashingReport;
10811                    } else if (app.notResponding) {
10812                        report = app.notRespondingReport;
10813                    }
10814
10815                    if (report != null) {
10816                        if (errList == null) {
10817                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10818                        }
10819                        errList.add(report);
10820                    } else {
10821                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10822                                " crashing = " + app.crashing +
10823                                " notResponding = " + app.notResponding);
10824                    }
10825                }
10826            }
10827        }
10828
10829        return errList;
10830    }
10831
10832    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10833        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10834            if (currApp != null) {
10835                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10836            }
10837            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10838        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10839            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10840        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10841            if (currApp != null) {
10842                currApp.lru = 0;
10843            }
10844            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10845        } else if (adj >= ProcessList.SERVICE_ADJ) {
10846            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10847        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10848            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10849        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10850            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10851        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10852            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10853        } else {
10854            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10855        }
10856    }
10857
10858    private void fillInProcMemInfo(ProcessRecord app,
10859            ActivityManager.RunningAppProcessInfo outInfo) {
10860        outInfo.pid = app.pid;
10861        outInfo.uid = app.info.uid;
10862        if (mHeavyWeightProcess == app) {
10863            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10864        }
10865        if (app.persistent) {
10866            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10867        }
10868        if (app.activities.size() > 0) {
10869            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10870        }
10871        outInfo.lastTrimLevel = app.trimMemoryLevel;
10872        int adj = app.curAdj;
10873        outInfo.importance = oomAdjToImportance(adj, outInfo);
10874        outInfo.importanceReasonCode = app.adjTypeCode;
10875        outInfo.processState = app.curProcState;
10876    }
10877
10878    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10879        enforceNotIsolatedCaller("getRunningAppProcesses");
10880        // Lazy instantiation of list
10881        List<ActivityManager.RunningAppProcessInfo> runList = null;
10882        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10883                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10884        int userId = UserHandle.getUserId(Binder.getCallingUid());
10885        synchronized (this) {
10886            // Iterate across all processes
10887            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10888                ProcessRecord app = mLruProcesses.get(i);
10889                if (!allUsers && app.userId != userId) {
10890                    continue;
10891                }
10892                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10893                    // Generate process state info for running application
10894                    ActivityManager.RunningAppProcessInfo currApp =
10895                        new ActivityManager.RunningAppProcessInfo(app.processName,
10896                                app.pid, app.getPackageList());
10897                    fillInProcMemInfo(app, currApp);
10898                    if (app.adjSource instanceof ProcessRecord) {
10899                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10900                        currApp.importanceReasonImportance = oomAdjToImportance(
10901                                app.adjSourceOom, null);
10902                    } else if (app.adjSource instanceof ActivityRecord) {
10903                        ActivityRecord r = (ActivityRecord)app.adjSource;
10904                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10905                    }
10906                    if (app.adjTarget instanceof ComponentName) {
10907                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10908                    }
10909                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10910                    //        + " lru=" + currApp.lru);
10911                    if (runList == null) {
10912                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10913                    }
10914                    runList.add(currApp);
10915                }
10916            }
10917        }
10918        return runList;
10919    }
10920
10921    public List<ApplicationInfo> getRunningExternalApplications() {
10922        enforceNotIsolatedCaller("getRunningExternalApplications");
10923        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10924        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10925        if (runningApps != null && runningApps.size() > 0) {
10926            Set<String> extList = new HashSet<String>();
10927            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10928                if (app.pkgList != null) {
10929                    for (String pkg : app.pkgList) {
10930                        extList.add(pkg);
10931                    }
10932                }
10933            }
10934            IPackageManager pm = AppGlobals.getPackageManager();
10935            for (String pkg : extList) {
10936                try {
10937                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10938                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10939                        retList.add(info);
10940                    }
10941                } catch (RemoteException e) {
10942                }
10943            }
10944        }
10945        return retList;
10946    }
10947
10948    @Override
10949    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10950        enforceNotIsolatedCaller("getMyMemoryState");
10951        synchronized (this) {
10952            ProcessRecord proc;
10953            synchronized (mPidsSelfLocked) {
10954                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10955            }
10956            fillInProcMemInfo(proc, outInfo);
10957        }
10958    }
10959
10960    @Override
10961    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10962        if (checkCallingPermission(android.Manifest.permission.DUMP)
10963                != PackageManager.PERMISSION_GRANTED) {
10964            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10965                    + Binder.getCallingPid()
10966                    + ", uid=" + Binder.getCallingUid()
10967                    + " without permission "
10968                    + android.Manifest.permission.DUMP);
10969            return;
10970        }
10971
10972        boolean dumpAll = false;
10973        boolean dumpClient = false;
10974        String dumpPackage = null;
10975
10976        int opti = 0;
10977        while (opti < args.length) {
10978            String opt = args[opti];
10979            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10980                break;
10981            }
10982            opti++;
10983            if ("-a".equals(opt)) {
10984                dumpAll = true;
10985            } else if ("-c".equals(opt)) {
10986                dumpClient = true;
10987            } else if ("-h".equals(opt)) {
10988                pw.println("Activity manager dump options:");
10989                pw.println("  [-a] [-c] [-h] [cmd] ...");
10990                pw.println("  cmd may be one of:");
10991                pw.println("    a[ctivities]: activity stack state");
10992                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10993                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
10994                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
10995                pw.println("    o[om]: out of memory management");
10996                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
10997                pw.println("    provider [COMP_SPEC]: provider client-side state");
10998                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
10999                pw.println("    service [COMP_SPEC]: service client-side state");
11000                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11001                pw.println("    all: dump all activities");
11002                pw.println("    top: dump the top activity");
11003                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11004                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11005                pw.println("    a partial substring in a component name, a");
11006                pw.println("    hex object identifier.");
11007                pw.println("  -a: include all available server state.");
11008                pw.println("  -c: include client state.");
11009                return;
11010            } else {
11011                pw.println("Unknown argument: " + opt + "; use -h for help");
11012            }
11013        }
11014
11015        long origId = Binder.clearCallingIdentity();
11016        boolean more = false;
11017        // Is the caller requesting to dump a particular piece of data?
11018        if (opti < args.length) {
11019            String cmd = args[opti];
11020            opti++;
11021            if ("activities".equals(cmd) || "a".equals(cmd)) {
11022                synchronized (this) {
11023                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11024                }
11025            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11026                String[] newArgs;
11027                String name;
11028                if (opti >= args.length) {
11029                    name = null;
11030                    newArgs = EMPTY_STRING_ARRAY;
11031                } else {
11032                    name = args[opti];
11033                    opti++;
11034                    newArgs = new String[args.length - opti];
11035                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11036                            args.length - opti);
11037                }
11038                synchronized (this) {
11039                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11040                }
11041            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11042                String[] newArgs;
11043                String name;
11044                if (opti >= args.length) {
11045                    name = null;
11046                    newArgs = EMPTY_STRING_ARRAY;
11047                } else {
11048                    name = args[opti];
11049                    opti++;
11050                    newArgs = new String[args.length - opti];
11051                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11052                            args.length - opti);
11053                }
11054                synchronized (this) {
11055                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11056                }
11057            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11058                String[] newArgs;
11059                String name;
11060                if (opti >= args.length) {
11061                    name = null;
11062                    newArgs = EMPTY_STRING_ARRAY;
11063                } else {
11064                    name = args[opti];
11065                    opti++;
11066                    newArgs = new String[args.length - opti];
11067                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11068                            args.length - opti);
11069                }
11070                synchronized (this) {
11071                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11072                }
11073            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11074                synchronized (this) {
11075                    dumpOomLocked(fd, pw, args, opti, true);
11076                }
11077            } else if ("provider".equals(cmd)) {
11078                String[] newArgs;
11079                String name;
11080                if (opti >= args.length) {
11081                    name = null;
11082                    newArgs = EMPTY_STRING_ARRAY;
11083                } else {
11084                    name = args[opti];
11085                    opti++;
11086                    newArgs = new String[args.length - opti];
11087                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11088                }
11089                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11090                    pw.println("No providers match: " + name);
11091                    pw.println("Use -h for help.");
11092                }
11093            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11094                synchronized (this) {
11095                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11096                }
11097            } else if ("service".equals(cmd)) {
11098                String[] newArgs;
11099                String name;
11100                if (opti >= args.length) {
11101                    name = null;
11102                    newArgs = EMPTY_STRING_ARRAY;
11103                } else {
11104                    name = args[opti];
11105                    opti++;
11106                    newArgs = new String[args.length - opti];
11107                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11108                            args.length - opti);
11109                }
11110                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11111                    pw.println("No services match: " + name);
11112                    pw.println("Use -h for help.");
11113                }
11114            } else if ("package".equals(cmd)) {
11115                String[] newArgs;
11116                if (opti >= args.length) {
11117                    pw.println("package: no package name specified");
11118                    pw.println("Use -h for help.");
11119                } else {
11120                    dumpPackage = args[opti];
11121                    opti++;
11122                    newArgs = new String[args.length - opti];
11123                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11124                            args.length - opti);
11125                    args = newArgs;
11126                    opti = 0;
11127                    more = true;
11128                }
11129            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11130                synchronized (this) {
11131                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11132                }
11133            } else {
11134                // Dumping a single activity?
11135                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11136                    pw.println("Bad activity command, or no activities match: " + cmd);
11137                    pw.println("Use -h for help.");
11138                }
11139            }
11140            if (!more) {
11141                Binder.restoreCallingIdentity(origId);
11142                return;
11143            }
11144        }
11145
11146        // No piece of data specified, dump everything.
11147        synchronized (this) {
11148            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11149            pw.println();
11150            if (dumpAll) {
11151                pw.println("-------------------------------------------------------------------------------");
11152            }
11153            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11154            pw.println();
11155            if (dumpAll) {
11156                pw.println("-------------------------------------------------------------------------------");
11157            }
11158            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11159            pw.println();
11160            if (dumpAll) {
11161                pw.println("-------------------------------------------------------------------------------");
11162            }
11163            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11164            pw.println();
11165            if (dumpAll) {
11166                pw.println("-------------------------------------------------------------------------------");
11167            }
11168            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11169            pw.println();
11170            if (dumpAll) {
11171                pw.println("-------------------------------------------------------------------------------");
11172            }
11173            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11174        }
11175        Binder.restoreCallingIdentity(origId);
11176    }
11177
11178    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11179            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11180        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11181
11182        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11183                dumpPackage);
11184        boolean needSep = printedAnything;
11185
11186        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11187                dumpPackage, needSep, "  mFocusedActivity: ");
11188        if (printed) {
11189            printedAnything = true;
11190            needSep = false;
11191        }
11192
11193        if (dumpPackage == null) {
11194            if (needSep) {
11195                pw.println();
11196            }
11197            needSep = true;
11198            printedAnything = true;
11199            mStackSupervisor.dump(pw, "  ");
11200        }
11201
11202        if (mRecentTasks.size() > 0) {
11203            boolean printedHeader = false;
11204
11205            final int N = mRecentTasks.size();
11206            for (int i=0; i<N; i++) {
11207                TaskRecord tr = mRecentTasks.get(i);
11208                if (dumpPackage != null) {
11209                    if (tr.realActivity == null ||
11210                            !dumpPackage.equals(tr.realActivity)) {
11211                        continue;
11212                    }
11213                }
11214                if (!printedHeader) {
11215                    if (needSep) {
11216                        pw.println();
11217                    }
11218                    pw.println("  Recent tasks:");
11219                    printedHeader = true;
11220                    printedAnything = true;
11221                }
11222                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11223                        pw.println(tr);
11224                if (dumpAll) {
11225                    mRecentTasks.get(i).dump(pw, "    ");
11226                }
11227            }
11228        }
11229
11230        if (!printedAnything) {
11231            pw.println("  (nothing)");
11232        }
11233    }
11234
11235    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11236            int opti, boolean dumpAll, String dumpPackage) {
11237        boolean needSep = false;
11238        boolean printedAnything = false;
11239        int numPers = 0;
11240
11241        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11242
11243        if (dumpAll) {
11244            final int NP = mProcessNames.getMap().size();
11245            for (int ip=0; ip<NP; ip++) {
11246                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11247                final int NA = procs.size();
11248                for (int ia=0; ia<NA; ia++) {
11249                    ProcessRecord r = procs.valueAt(ia);
11250                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11251                        continue;
11252                    }
11253                    if (!needSep) {
11254                        pw.println("  All known processes:");
11255                        needSep = true;
11256                        printedAnything = true;
11257                    }
11258                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11259                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11260                        pw.print(" "); pw.println(r);
11261                    r.dump(pw, "    ");
11262                    if (r.persistent) {
11263                        numPers++;
11264                    }
11265                }
11266            }
11267        }
11268
11269        if (mIsolatedProcesses.size() > 0) {
11270            boolean printed = false;
11271            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11272                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11273                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11274                    continue;
11275                }
11276                if (!printed) {
11277                    if (needSep) {
11278                        pw.println();
11279                    }
11280                    pw.println("  Isolated process list (sorted by uid):");
11281                    printedAnything = true;
11282                    printed = true;
11283                    needSep = true;
11284                }
11285                pw.println(String.format("%sIsolated #%2d: %s",
11286                        "    ", i, r.toString()));
11287            }
11288        }
11289
11290        if (mLruProcesses.size() > 0) {
11291            if (needSep) {
11292                pw.println();
11293            }
11294            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11295                    pw.print(" total, non-act at ");
11296                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11297                    pw.print(", non-svc at ");
11298                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11299                    pw.println("):");
11300            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11301            needSep = true;
11302            printedAnything = true;
11303        }
11304
11305        if (dumpAll || dumpPackage != null) {
11306            synchronized (mPidsSelfLocked) {
11307                boolean printed = false;
11308                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11309                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11310                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11311                        continue;
11312                    }
11313                    if (!printed) {
11314                        if (needSep) pw.println();
11315                        needSep = true;
11316                        pw.println("  PID mappings:");
11317                        printed = true;
11318                        printedAnything = true;
11319                    }
11320                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11321                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11322                }
11323            }
11324        }
11325
11326        if (mForegroundProcesses.size() > 0) {
11327            synchronized (mPidsSelfLocked) {
11328                boolean printed = false;
11329                for (int i=0; i<mForegroundProcesses.size(); i++) {
11330                    ProcessRecord r = mPidsSelfLocked.get(
11331                            mForegroundProcesses.valueAt(i).pid);
11332                    if (dumpPackage != null && (r == null
11333                            || !r.pkgList.containsKey(dumpPackage))) {
11334                        continue;
11335                    }
11336                    if (!printed) {
11337                        if (needSep) pw.println();
11338                        needSep = true;
11339                        pw.println("  Foreground Processes:");
11340                        printed = true;
11341                        printedAnything = true;
11342                    }
11343                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11344                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11345                }
11346            }
11347        }
11348
11349        if (mPersistentStartingProcesses.size() > 0) {
11350            if (needSep) pw.println();
11351            needSep = true;
11352            printedAnything = true;
11353            pw.println("  Persisent processes that are starting:");
11354            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11355                    "Starting Norm", "Restarting PERS", dumpPackage);
11356        }
11357
11358        if (mRemovedProcesses.size() > 0) {
11359            if (needSep) pw.println();
11360            needSep = true;
11361            printedAnything = true;
11362            pw.println("  Processes that are being removed:");
11363            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11364                    "Removed Norm", "Removed PERS", dumpPackage);
11365        }
11366
11367        if (mProcessesOnHold.size() > 0) {
11368            if (needSep) pw.println();
11369            needSep = true;
11370            printedAnything = true;
11371            pw.println("  Processes that are on old until the system is ready:");
11372            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11373                    "OnHold Norm", "OnHold PERS", dumpPackage);
11374        }
11375
11376        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11377
11378        if (mProcessCrashTimes.getMap().size() > 0) {
11379            boolean printed = false;
11380            long now = SystemClock.uptimeMillis();
11381            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11382            final int NP = pmap.size();
11383            for (int ip=0; ip<NP; ip++) {
11384                String pname = pmap.keyAt(ip);
11385                SparseArray<Long> uids = pmap.valueAt(ip);
11386                final int N = uids.size();
11387                for (int i=0; i<N; i++) {
11388                    int puid = uids.keyAt(i);
11389                    ProcessRecord r = mProcessNames.get(pname, puid);
11390                    if (dumpPackage != null && (r == null
11391                            || !r.pkgList.containsKey(dumpPackage))) {
11392                        continue;
11393                    }
11394                    if (!printed) {
11395                        if (needSep) pw.println();
11396                        needSep = true;
11397                        pw.println("  Time since processes crashed:");
11398                        printed = true;
11399                        printedAnything = true;
11400                    }
11401                    pw.print("    Process "); pw.print(pname);
11402                            pw.print(" uid "); pw.print(puid);
11403                            pw.print(": last crashed ");
11404                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11405                            pw.println(" ago");
11406                }
11407            }
11408        }
11409
11410        if (mBadProcesses.getMap().size() > 0) {
11411            boolean printed = false;
11412            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11413            final int NP = pmap.size();
11414            for (int ip=0; ip<NP; ip++) {
11415                String pname = pmap.keyAt(ip);
11416                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11417                final int N = uids.size();
11418                for (int i=0; i<N; i++) {
11419                    int puid = uids.keyAt(i);
11420                    ProcessRecord r = mProcessNames.get(pname, puid);
11421                    if (dumpPackage != null && (r == null
11422                            || !r.pkgList.containsKey(dumpPackage))) {
11423                        continue;
11424                    }
11425                    if (!printed) {
11426                        if (needSep) pw.println();
11427                        needSep = true;
11428                        pw.println("  Bad processes:");
11429                        printedAnything = true;
11430                    }
11431                    BadProcessInfo info = uids.valueAt(i);
11432                    pw.print("    Bad process "); pw.print(pname);
11433                            pw.print(" uid "); pw.print(puid);
11434                            pw.print(": crashed at time "); pw.println(info.time);
11435                    if (info.shortMsg != null) {
11436                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11437                    }
11438                    if (info.longMsg != null) {
11439                        pw.print("      Long msg: "); pw.println(info.longMsg);
11440                    }
11441                    if (info.stack != null) {
11442                        pw.println("      Stack:");
11443                        int lastPos = 0;
11444                        for (int pos=0; pos<info.stack.length(); pos++) {
11445                            if (info.stack.charAt(pos) == '\n') {
11446                                pw.print("        ");
11447                                pw.write(info.stack, lastPos, pos-lastPos);
11448                                pw.println();
11449                                lastPos = pos+1;
11450                            }
11451                        }
11452                        if (lastPos < info.stack.length()) {
11453                            pw.print("        ");
11454                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11455                            pw.println();
11456                        }
11457                    }
11458                }
11459            }
11460        }
11461
11462        if (dumpPackage == null) {
11463            pw.println();
11464            needSep = false;
11465            pw.println("  mStartedUsers:");
11466            for (int i=0; i<mStartedUsers.size(); i++) {
11467                UserStartedState uss = mStartedUsers.valueAt(i);
11468                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11469                        pw.print(": "); uss.dump("", pw);
11470            }
11471            pw.print("  mStartedUserArray: [");
11472            for (int i=0; i<mStartedUserArray.length; i++) {
11473                if (i > 0) pw.print(", ");
11474                pw.print(mStartedUserArray[i]);
11475            }
11476            pw.println("]");
11477            pw.print("  mUserLru: [");
11478            for (int i=0; i<mUserLru.size(); i++) {
11479                if (i > 0) pw.print(", ");
11480                pw.print(mUserLru.get(i));
11481            }
11482            pw.println("]");
11483            if (dumpAll) {
11484                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11485            }
11486        }
11487        if (mHomeProcess != null && (dumpPackage == null
11488                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11489            if (needSep) {
11490                pw.println();
11491                needSep = false;
11492            }
11493            pw.println("  mHomeProcess: " + mHomeProcess);
11494        }
11495        if (mPreviousProcess != null && (dumpPackage == null
11496                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11497            if (needSep) {
11498                pw.println();
11499                needSep = false;
11500            }
11501            pw.println("  mPreviousProcess: " + mPreviousProcess);
11502        }
11503        if (dumpAll) {
11504            StringBuilder sb = new StringBuilder(128);
11505            sb.append("  mPreviousProcessVisibleTime: ");
11506            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11507            pw.println(sb);
11508        }
11509        if (mHeavyWeightProcess != null && (dumpPackage == null
11510                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11511            if (needSep) {
11512                pw.println();
11513                needSep = false;
11514            }
11515            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11516        }
11517        if (dumpPackage == null) {
11518            pw.println("  mConfiguration: " + mConfiguration);
11519        }
11520        if (dumpAll) {
11521            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11522            if (mCompatModePackages.getPackages().size() > 0) {
11523                boolean printed = false;
11524                for (Map.Entry<String, Integer> entry
11525                        : mCompatModePackages.getPackages().entrySet()) {
11526                    String pkg = entry.getKey();
11527                    int mode = entry.getValue();
11528                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11529                        continue;
11530                    }
11531                    if (!printed) {
11532                        pw.println("  mScreenCompatPackages:");
11533                        printed = true;
11534                    }
11535                    pw.print("    "); pw.print(pkg); pw.print(": ");
11536                            pw.print(mode); pw.println();
11537                }
11538            }
11539        }
11540        if (dumpPackage == null) {
11541            if (mSleeping || mWentToSleep || mLockScreenShown) {
11542                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11543                        + " mLockScreenShown " + mLockScreenShown);
11544            }
11545            if (mShuttingDown || mRunningVoice) {
11546                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11547            }
11548        }
11549        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11550                || mOrigWaitForDebugger) {
11551            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11552                    || dumpPackage.equals(mOrigDebugApp)) {
11553                if (needSep) {
11554                    pw.println();
11555                    needSep = false;
11556                }
11557                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11558                        + " mDebugTransient=" + mDebugTransient
11559                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11560            }
11561        }
11562        if (mOpenGlTraceApp != null) {
11563            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11564                if (needSep) {
11565                    pw.println();
11566                    needSep = false;
11567                }
11568                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11569            }
11570        }
11571        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11572                || mProfileFd != null) {
11573            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11574                if (needSep) {
11575                    pw.println();
11576                    needSep = false;
11577                }
11578                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11579                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11580                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11581                        + mAutoStopProfiler);
11582            }
11583        }
11584        if (dumpPackage == null) {
11585            if (mAlwaysFinishActivities || mController != null) {
11586                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11587                        + " mController=" + mController);
11588            }
11589            if (dumpAll) {
11590                pw.println("  Total persistent processes: " + numPers);
11591                pw.println("  mProcessesReady=" + mProcessesReady
11592                        + " mSystemReady=" + mSystemReady);
11593                pw.println("  mBooting=" + mBooting
11594                        + " mBooted=" + mBooted
11595                        + " mFactoryTest=" + mFactoryTest);
11596                pw.print("  mLastPowerCheckRealtime=");
11597                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11598                        pw.println("");
11599                pw.print("  mLastPowerCheckUptime=");
11600                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11601                        pw.println("");
11602                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11603                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11604                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11605                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11606                        + " (" + mLruProcesses.size() + " total)"
11607                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11608                        + " mNumServiceProcs=" + mNumServiceProcs
11609                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11610                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11611                        + " mLastMemoryLevel" + mLastMemoryLevel
11612                        + " mLastNumProcesses" + mLastNumProcesses);
11613                long now = SystemClock.uptimeMillis();
11614                pw.print("  mLastIdleTime=");
11615                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11616                        pw.print(" mLowRamSinceLastIdle=");
11617                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11618                        pw.println();
11619            }
11620        }
11621
11622        if (!printedAnything) {
11623            pw.println("  (nothing)");
11624        }
11625    }
11626
11627    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11628            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11629        if (mProcessesToGc.size() > 0) {
11630            boolean printed = false;
11631            long now = SystemClock.uptimeMillis();
11632            for (int i=0; i<mProcessesToGc.size(); i++) {
11633                ProcessRecord proc = mProcessesToGc.get(i);
11634                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11635                    continue;
11636                }
11637                if (!printed) {
11638                    if (needSep) pw.println();
11639                    needSep = true;
11640                    pw.println("  Processes that are waiting to GC:");
11641                    printed = true;
11642                }
11643                pw.print("    Process "); pw.println(proc);
11644                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11645                        pw.print(", last gced=");
11646                        pw.print(now-proc.lastRequestedGc);
11647                        pw.print(" ms ago, last lowMem=");
11648                        pw.print(now-proc.lastLowMemory);
11649                        pw.println(" ms ago");
11650
11651            }
11652        }
11653        return needSep;
11654    }
11655
11656    void printOomLevel(PrintWriter pw, String name, int adj) {
11657        pw.print("    ");
11658        if (adj >= 0) {
11659            pw.print(' ');
11660            if (adj < 10) pw.print(' ');
11661        } else {
11662            if (adj > -10) pw.print(' ');
11663        }
11664        pw.print(adj);
11665        pw.print(": ");
11666        pw.print(name);
11667        pw.print(" (");
11668        pw.print(mProcessList.getMemLevel(adj)/1024);
11669        pw.println(" kB)");
11670    }
11671
11672    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11673            int opti, boolean dumpAll) {
11674        boolean needSep = false;
11675
11676        if (mLruProcesses.size() > 0) {
11677            if (needSep) pw.println();
11678            needSep = true;
11679            pw.println("  OOM levels:");
11680            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11681            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11682            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11683            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11684            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11685            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11686            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11687            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11688            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11689            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11690            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11691            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11692            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11693
11694            if (needSep) pw.println();
11695            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11696                    pw.print(" total, non-act at ");
11697                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11698                    pw.print(", non-svc at ");
11699                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11700                    pw.println("):");
11701            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11702            needSep = true;
11703        }
11704
11705        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11706
11707        pw.println();
11708        pw.println("  mHomeProcess: " + mHomeProcess);
11709        pw.println("  mPreviousProcess: " + mPreviousProcess);
11710        if (mHeavyWeightProcess != null) {
11711            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11712        }
11713
11714        return true;
11715    }
11716
11717    /**
11718     * There are three ways to call this:
11719     *  - no provider specified: dump all the providers
11720     *  - a flattened component name that matched an existing provider was specified as the
11721     *    first arg: dump that one provider
11722     *  - the first arg isn't the flattened component name of an existing provider:
11723     *    dump all providers whose component contains the first arg as a substring
11724     */
11725    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11726            int opti, boolean dumpAll) {
11727        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11728    }
11729
11730    static class ItemMatcher {
11731        ArrayList<ComponentName> components;
11732        ArrayList<String> strings;
11733        ArrayList<Integer> objects;
11734        boolean all;
11735
11736        ItemMatcher() {
11737            all = true;
11738        }
11739
11740        void build(String name) {
11741            ComponentName componentName = ComponentName.unflattenFromString(name);
11742            if (componentName != null) {
11743                if (components == null) {
11744                    components = new ArrayList<ComponentName>();
11745                }
11746                components.add(componentName);
11747                all = false;
11748            } else {
11749                int objectId = 0;
11750                // Not a '/' separated full component name; maybe an object ID?
11751                try {
11752                    objectId = Integer.parseInt(name, 16);
11753                    if (objects == null) {
11754                        objects = new ArrayList<Integer>();
11755                    }
11756                    objects.add(objectId);
11757                    all = false;
11758                } catch (RuntimeException e) {
11759                    // Not an integer; just do string match.
11760                    if (strings == null) {
11761                        strings = new ArrayList<String>();
11762                    }
11763                    strings.add(name);
11764                    all = false;
11765                }
11766            }
11767        }
11768
11769        int build(String[] args, int opti) {
11770            for (; opti<args.length; opti++) {
11771                String name = args[opti];
11772                if ("--".equals(name)) {
11773                    return opti+1;
11774                }
11775                build(name);
11776            }
11777            return opti;
11778        }
11779
11780        boolean match(Object object, ComponentName comp) {
11781            if (all) {
11782                return true;
11783            }
11784            if (components != null) {
11785                for (int i=0; i<components.size(); i++) {
11786                    if (components.get(i).equals(comp)) {
11787                        return true;
11788                    }
11789                }
11790            }
11791            if (objects != null) {
11792                for (int i=0; i<objects.size(); i++) {
11793                    if (System.identityHashCode(object) == objects.get(i)) {
11794                        return true;
11795                    }
11796                }
11797            }
11798            if (strings != null) {
11799                String flat = comp.flattenToString();
11800                for (int i=0; i<strings.size(); i++) {
11801                    if (flat.contains(strings.get(i))) {
11802                        return true;
11803                    }
11804                }
11805            }
11806            return false;
11807        }
11808    }
11809
11810    /**
11811     * There are three things that cmd can be:
11812     *  - a flattened component name that matches an existing activity
11813     *  - the cmd arg isn't the flattened component name of an existing activity:
11814     *    dump all activity whose component contains the cmd as a substring
11815     *  - A hex number of the ActivityRecord object instance.
11816     */
11817    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11818            int opti, boolean dumpAll) {
11819        ArrayList<ActivityRecord> activities;
11820
11821        synchronized (this) {
11822            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11823        }
11824
11825        if (activities.size() <= 0) {
11826            return false;
11827        }
11828
11829        String[] newArgs = new String[args.length - opti];
11830        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11831
11832        TaskRecord lastTask = null;
11833        boolean needSep = false;
11834        for (int i=activities.size()-1; i>=0; i--) {
11835            ActivityRecord r = activities.get(i);
11836            if (needSep) {
11837                pw.println();
11838            }
11839            needSep = true;
11840            synchronized (this) {
11841                if (lastTask != r.task) {
11842                    lastTask = r.task;
11843                    pw.print("TASK "); pw.print(lastTask.affinity);
11844                            pw.print(" id="); pw.println(lastTask.taskId);
11845                    if (dumpAll) {
11846                        lastTask.dump(pw, "  ");
11847                    }
11848                }
11849            }
11850            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11851        }
11852        return true;
11853    }
11854
11855    /**
11856     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11857     * there is a thread associated with the activity.
11858     */
11859    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11860            final ActivityRecord r, String[] args, boolean dumpAll) {
11861        String innerPrefix = prefix + "  ";
11862        synchronized (this) {
11863            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11864                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11865                    pw.print(" pid=");
11866                    if (r.app != null) pw.println(r.app.pid);
11867                    else pw.println("(not running)");
11868            if (dumpAll) {
11869                r.dump(pw, innerPrefix);
11870            }
11871        }
11872        if (r.app != null && r.app.thread != null) {
11873            // flush anything that is already in the PrintWriter since the thread is going
11874            // to write to the file descriptor directly
11875            pw.flush();
11876            try {
11877                TransferPipe tp = new TransferPipe();
11878                try {
11879                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11880                            r.appToken, innerPrefix, args);
11881                    tp.go(fd);
11882                } finally {
11883                    tp.kill();
11884                }
11885            } catch (IOException e) {
11886                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11887            } catch (RemoteException e) {
11888                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11889            }
11890        }
11891    }
11892
11893    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11894            int opti, boolean dumpAll, String dumpPackage) {
11895        boolean needSep = false;
11896        boolean onlyHistory = false;
11897        boolean printedAnything = false;
11898
11899        if ("history".equals(dumpPackage)) {
11900            if (opti < args.length && "-s".equals(args[opti])) {
11901                dumpAll = false;
11902            }
11903            onlyHistory = true;
11904            dumpPackage = null;
11905        }
11906
11907        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11908        if (!onlyHistory && dumpAll) {
11909            if (mRegisteredReceivers.size() > 0) {
11910                boolean printed = false;
11911                Iterator it = mRegisteredReceivers.values().iterator();
11912                while (it.hasNext()) {
11913                    ReceiverList r = (ReceiverList)it.next();
11914                    if (dumpPackage != null && (r.app == null ||
11915                            !dumpPackage.equals(r.app.info.packageName))) {
11916                        continue;
11917                    }
11918                    if (!printed) {
11919                        pw.println("  Registered Receivers:");
11920                        needSep = true;
11921                        printed = true;
11922                        printedAnything = true;
11923                    }
11924                    pw.print("  * "); pw.println(r);
11925                    r.dump(pw, "    ");
11926                }
11927            }
11928
11929            if (mReceiverResolver.dump(pw, needSep ?
11930                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11931                    "    ", dumpPackage, false)) {
11932                needSep = true;
11933                printedAnything = true;
11934            }
11935        }
11936
11937        for (BroadcastQueue q : mBroadcastQueues) {
11938            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11939            printedAnything |= needSep;
11940        }
11941
11942        needSep = true;
11943
11944        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11945            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11946                if (needSep) {
11947                    pw.println();
11948                }
11949                needSep = true;
11950                printedAnything = true;
11951                pw.print("  Sticky broadcasts for user ");
11952                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11953                StringBuilder sb = new StringBuilder(128);
11954                for (Map.Entry<String, ArrayList<Intent>> ent
11955                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11956                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11957                    if (dumpAll) {
11958                        pw.println(":");
11959                        ArrayList<Intent> intents = ent.getValue();
11960                        final int N = intents.size();
11961                        for (int i=0; i<N; i++) {
11962                            sb.setLength(0);
11963                            sb.append("    Intent: ");
11964                            intents.get(i).toShortString(sb, false, true, false, false);
11965                            pw.println(sb.toString());
11966                            Bundle bundle = intents.get(i).getExtras();
11967                            if (bundle != null) {
11968                                pw.print("      ");
11969                                pw.println(bundle.toString());
11970                            }
11971                        }
11972                    } else {
11973                        pw.println("");
11974                    }
11975                }
11976            }
11977        }
11978
11979        if (!onlyHistory && dumpAll) {
11980            pw.println();
11981            for (BroadcastQueue queue : mBroadcastQueues) {
11982                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11983                        + queue.mBroadcastsScheduled);
11984            }
11985            pw.println("  mHandler:");
11986            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11987            needSep = true;
11988            printedAnything = true;
11989        }
11990
11991        if (!printedAnything) {
11992            pw.println("  (nothing)");
11993        }
11994    }
11995
11996    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11997            int opti, boolean dumpAll, String dumpPackage) {
11998        boolean needSep;
11999        boolean printedAnything = false;
12000
12001        ItemMatcher matcher = new ItemMatcher();
12002        matcher.build(args, opti);
12003
12004        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12005
12006        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12007        printedAnything |= needSep;
12008
12009        if (mLaunchingProviders.size() > 0) {
12010            boolean printed = false;
12011            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12012                ContentProviderRecord r = mLaunchingProviders.get(i);
12013                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12014                    continue;
12015                }
12016                if (!printed) {
12017                    if (needSep) pw.println();
12018                    needSep = true;
12019                    pw.println("  Launching content providers:");
12020                    printed = true;
12021                    printedAnything = true;
12022                }
12023                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12024                        pw.println(r);
12025            }
12026        }
12027
12028        if (mGrantedUriPermissions.size() > 0) {
12029            boolean printed = false;
12030            int dumpUid = -2;
12031            if (dumpPackage != null) {
12032                try {
12033                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12034                } catch (NameNotFoundException e) {
12035                    dumpUid = -1;
12036                }
12037            }
12038            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12039                int uid = mGrantedUriPermissions.keyAt(i);
12040                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12041                    continue;
12042                }
12043                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12044                if (!printed) {
12045                    if (needSep) pw.println();
12046                    needSep = true;
12047                    pw.println("  Granted Uri Permissions:");
12048                    printed = true;
12049                    printedAnything = true;
12050                }
12051                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12052                for (UriPermission perm : perms.values()) {
12053                    pw.print("    "); pw.println(perm);
12054                    if (dumpAll) {
12055                        perm.dump(pw, "      ");
12056                    }
12057                }
12058            }
12059        }
12060
12061        if (!printedAnything) {
12062            pw.println("  (nothing)");
12063        }
12064    }
12065
12066    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12067            int opti, boolean dumpAll, String dumpPackage) {
12068        boolean printed = false;
12069
12070        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12071
12072        if (mIntentSenderRecords.size() > 0) {
12073            Iterator<WeakReference<PendingIntentRecord>> it
12074                    = mIntentSenderRecords.values().iterator();
12075            while (it.hasNext()) {
12076                WeakReference<PendingIntentRecord> ref = it.next();
12077                PendingIntentRecord rec = ref != null ? ref.get(): null;
12078                if (dumpPackage != null && (rec == null
12079                        || !dumpPackage.equals(rec.key.packageName))) {
12080                    continue;
12081                }
12082                printed = true;
12083                if (rec != null) {
12084                    pw.print("  * "); pw.println(rec);
12085                    if (dumpAll) {
12086                        rec.dump(pw, "    ");
12087                    }
12088                } else {
12089                    pw.print("  * "); pw.println(ref);
12090                }
12091            }
12092        }
12093
12094        if (!printed) {
12095            pw.println("  (nothing)");
12096        }
12097    }
12098
12099    private static final int dumpProcessList(PrintWriter pw,
12100            ActivityManagerService service, List list,
12101            String prefix, String normalLabel, String persistentLabel,
12102            String dumpPackage) {
12103        int numPers = 0;
12104        final int N = list.size()-1;
12105        for (int i=N; i>=0; i--) {
12106            ProcessRecord r = (ProcessRecord)list.get(i);
12107            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12108                continue;
12109            }
12110            pw.println(String.format("%s%s #%2d: %s",
12111                    prefix, (r.persistent ? persistentLabel : normalLabel),
12112                    i, r.toString()));
12113            if (r.persistent) {
12114                numPers++;
12115            }
12116        }
12117        return numPers;
12118    }
12119
12120    private static final boolean dumpProcessOomList(PrintWriter pw,
12121            ActivityManagerService service, List<ProcessRecord> origList,
12122            String prefix, String normalLabel, String persistentLabel,
12123            boolean inclDetails, String dumpPackage) {
12124
12125        ArrayList<Pair<ProcessRecord, Integer>> list
12126                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12127        for (int i=0; i<origList.size(); i++) {
12128            ProcessRecord r = origList.get(i);
12129            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12130                continue;
12131            }
12132            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12133        }
12134
12135        if (list.size() <= 0) {
12136            return false;
12137        }
12138
12139        Comparator<Pair<ProcessRecord, Integer>> comparator
12140                = new Comparator<Pair<ProcessRecord, Integer>>() {
12141            @Override
12142            public int compare(Pair<ProcessRecord, Integer> object1,
12143                    Pair<ProcessRecord, Integer> object2) {
12144                if (object1.first.setAdj != object2.first.setAdj) {
12145                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12146                }
12147                if (object1.second.intValue() != object2.second.intValue()) {
12148                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12149                }
12150                return 0;
12151            }
12152        };
12153
12154        Collections.sort(list, comparator);
12155
12156        final long curRealtime = SystemClock.elapsedRealtime();
12157        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12158        final long curUptime = SystemClock.uptimeMillis();
12159        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12160
12161        for (int i=list.size()-1; i>=0; i--) {
12162            ProcessRecord r = list.get(i).first;
12163            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12164            char schedGroup;
12165            switch (r.setSchedGroup) {
12166                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12167                    schedGroup = 'B';
12168                    break;
12169                case Process.THREAD_GROUP_DEFAULT:
12170                    schedGroup = 'F';
12171                    break;
12172                default:
12173                    schedGroup = '?';
12174                    break;
12175            }
12176            char foreground;
12177            if (r.foregroundActivities) {
12178                foreground = 'A';
12179            } else if (r.foregroundServices) {
12180                foreground = 'S';
12181            } else {
12182                foreground = ' ';
12183            }
12184            String procState = ProcessList.makeProcStateString(r.curProcState);
12185            pw.print(prefix);
12186            pw.print(r.persistent ? persistentLabel : normalLabel);
12187            pw.print(" #");
12188            int num = (origList.size()-1)-list.get(i).second;
12189            if (num < 10) pw.print(' ');
12190            pw.print(num);
12191            pw.print(": ");
12192            pw.print(oomAdj);
12193            pw.print(' ');
12194            pw.print(schedGroup);
12195            pw.print('/');
12196            pw.print(foreground);
12197            pw.print('/');
12198            pw.print(procState);
12199            pw.print(" trm:");
12200            if (r.trimMemoryLevel < 10) pw.print(' ');
12201            pw.print(r.trimMemoryLevel);
12202            pw.print(' ');
12203            pw.print(r.toShortString());
12204            pw.print(" (");
12205            pw.print(r.adjType);
12206            pw.println(')');
12207            if (r.adjSource != null || r.adjTarget != null) {
12208                pw.print(prefix);
12209                pw.print("    ");
12210                if (r.adjTarget instanceof ComponentName) {
12211                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12212                } else if (r.adjTarget != null) {
12213                    pw.print(r.adjTarget.toString());
12214                } else {
12215                    pw.print("{null}");
12216                }
12217                pw.print("<=");
12218                if (r.adjSource instanceof ProcessRecord) {
12219                    pw.print("Proc{");
12220                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12221                    pw.println("}");
12222                } else if (r.adjSource != null) {
12223                    pw.println(r.adjSource.toString());
12224                } else {
12225                    pw.println("{null}");
12226                }
12227            }
12228            if (inclDetails) {
12229                pw.print(prefix);
12230                pw.print("    ");
12231                pw.print("oom: max="); pw.print(r.maxAdj);
12232                pw.print(" curRaw="); pw.print(r.curRawAdj);
12233                pw.print(" setRaw="); pw.print(r.setRawAdj);
12234                pw.print(" cur="); pw.print(r.curAdj);
12235                pw.print(" set="); pw.println(r.setAdj);
12236                pw.print(prefix);
12237                pw.print("    ");
12238                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12239                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12240                pw.print(" lastPss="); pw.print(r.lastPss);
12241                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12242                pw.print(prefix);
12243                pw.print("    ");
12244                pw.print("keeping="); pw.print(r.keeping);
12245                pw.print(" cached="); pw.print(r.cached);
12246                pw.print(" empty="); pw.print(r.empty);
12247                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12248
12249                if (!r.keeping) {
12250                    if (r.lastWakeTime != 0) {
12251                        long wtime;
12252                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12253                        synchronized (stats) {
12254                            wtime = stats.getProcessWakeTime(r.info.uid,
12255                                    r.pid, curRealtime);
12256                        }
12257                        long timeUsed = wtime - r.lastWakeTime;
12258                        pw.print(prefix);
12259                        pw.print("    ");
12260                        pw.print("keep awake over ");
12261                        TimeUtils.formatDuration(realtimeSince, pw);
12262                        pw.print(" used ");
12263                        TimeUtils.formatDuration(timeUsed, pw);
12264                        pw.print(" (");
12265                        pw.print((timeUsed*100)/realtimeSince);
12266                        pw.println("%)");
12267                    }
12268                    if (r.lastCpuTime != 0) {
12269                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12270                        pw.print(prefix);
12271                        pw.print("    ");
12272                        pw.print("run cpu over ");
12273                        TimeUtils.formatDuration(uptimeSince, pw);
12274                        pw.print(" used ");
12275                        TimeUtils.formatDuration(timeUsed, pw);
12276                        pw.print(" (");
12277                        pw.print((timeUsed*100)/uptimeSince);
12278                        pw.println("%)");
12279                    }
12280                }
12281            }
12282        }
12283        return true;
12284    }
12285
12286    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12287        ArrayList<ProcessRecord> procs;
12288        synchronized (this) {
12289            if (args != null && args.length > start
12290                    && args[start].charAt(0) != '-') {
12291                procs = new ArrayList<ProcessRecord>();
12292                int pid = -1;
12293                try {
12294                    pid = Integer.parseInt(args[start]);
12295                } catch (NumberFormatException e) {
12296                }
12297                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12298                    ProcessRecord proc = mLruProcesses.get(i);
12299                    if (proc.pid == pid) {
12300                        procs.add(proc);
12301                    } else if (proc.processName.equals(args[start])) {
12302                        procs.add(proc);
12303                    }
12304                }
12305                if (procs.size() <= 0) {
12306                    return null;
12307                }
12308            } else {
12309                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12310            }
12311        }
12312        return procs;
12313    }
12314
12315    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12316            PrintWriter pw, String[] args) {
12317        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12318        if (procs == null) {
12319            pw.println("No process found for: " + args[0]);
12320            return;
12321        }
12322
12323        long uptime = SystemClock.uptimeMillis();
12324        long realtime = SystemClock.elapsedRealtime();
12325        pw.println("Applications Graphics Acceleration Info:");
12326        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12327
12328        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12329            ProcessRecord r = procs.get(i);
12330            if (r.thread != null) {
12331                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12332                pw.flush();
12333                try {
12334                    TransferPipe tp = new TransferPipe();
12335                    try {
12336                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12337                        tp.go(fd);
12338                    } finally {
12339                        tp.kill();
12340                    }
12341                } catch (IOException e) {
12342                    pw.println("Failure while dumping the app: " + r);
12343                    pw.flush();
12344                } catch (RemoteException e) {
12345                    pw.println("Got a RemoteException while dumping the app " + r);
12346                    pw.flush();
12347                }
12348            }
12349        }
12350    }
12351
12352    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12353        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12354        if (procs == null) {
12355            pw.println("No process found for: " + args[0]);
12356            return;
12357        }
12358
12359        pw.println("Applications Database Info:");
12360
12361        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12362            ProcessRecord r = procs.get(i);
12363            if (r.thread != null) {
12364                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12365                pw.flush();
12366                try {
12367                    TransferPipe tp = new TransferPipe();
12368                    try {
12369                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12370                        tp.go(fd);
12371                    } finally {
12372                        tp.kill();
12373                    }
12374                } catch (IOException e) {
12375                    pw.println("Failure while dumping the app: " + r);
12376                    pw.flush();
12377                } catch (RemoteException e) {
12378                    pw.println("Got a RemoteException while dumping the app " + r);
12379                    pw.flush();
12380                }
12381            }
12382        }
12383    }
12384
12385    final static class MemItem {
12386        final boolean isProc;
12387        final String label;
12388        final String shortLabel;
12389        final long pss;
12390        final int id;
12391        final boolean hasActivities;
12392        ArrayList<MemItem> subitems;
12393
12394        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12395                boolean _hasActivities) {
12396            isProc = true;
12397            label = _label;
12398            shortLabel = _shortLabel;
12399            pss = _pss;
12400            id = _id;
12401            hasActivities = _hasActivities;
12402        }
12403
12404        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12405            isProc = false;
12406            label = _label;
12407            shortLabel = _shortLabel;
12408            pss = _pss;
12409            id = _id;
12410            hasActivities = false;
12411        }
12412    }
12413
12414    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12415            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12416        if (sort && !isCompact) {
12417            Collections.sort(items, new Comparator<MemItem>() {
12418                @Override
12419                public int compare(MemItem lhs, MemItem rhs) {
12420                    if (lhs.pss < rhs.pss) {
12421                        return 1;
12422                    } else if (lhs.pss > rhs.pss) {
12423                        return -1;
12424                    }
12425                    return 0;
12426                }
12427            });
12428        }
12429
12430        for (int i=0; i<items.size(); i++) {
12431            MemItem mi = items.get(i);
12432            if (!isCompact) {
12433                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12434            } else if (mi.isProc) {
12435                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12436                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12437                pw.println(mi.hasActivities ? ",a" : ",e");
12438            } else {
12439                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12440                pw.println(mi.pss);
12441            }
12442            if (mi.subitems != null) {
12443                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12444                        true, isCompact);
12445            }
12446        }
12447    }
12448
12449    // These are in KB.
12450    static final long[] DUMP_MEM_BUCKETS = new long[] {
12451        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12452        120*1024, 160*1024, 200*1024,
12453        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12454        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12455    };
12456
12457    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12458            boolean stackLike) {
12459        int start = label.lastIndexOf('.');
12460        if (start >= 0) start++;
12461        else start = 0;
12462        int end = label.length();
12463        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12464            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12465                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12466                out.append(bucket);
12467                out.append(stackLike ? "MB." : "MB ");
12468                out.append(label, start, end);
12469                return;
12470            }
12471        }
12472        out.append(memKB/1024);
12473        out.append(stackLike ? "MB." : "MB ");
12474        out.append(label, start, end);
12475    }
12476
12477    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12478            ProcessList.NATIVE_ADJ,
12479            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12480            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12481            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12482            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12483            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12484    };
12485    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12486            "Native",
12487            "System", "Persistent", "Foreground",
12488            "Visible", "Perceptible",
12489            "Heavy Weight", "Backup",
12490            "A Services", "Home",
12491            "Previous", "B Services", "Cached"
12492    };
12493    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12494            "native",
12495            "sys", "pers", "fore",
12496            "vis", "percept",
12497            "heavy", "backup",
12498            "servicea", "home",
12499            "prev", "serviceb", "cached"
12500    };
12501
12502    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12503            long realtime, boolean isCheckinRequest, boolean isCompact) {
12504        if (isCheckinRequest || isCompact) {
12505            // short checkin version
12506            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12507        } else {
12508            pw.println("Applications Memory Usage (kB):");
12509            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12510        }
12511    }
12512
12513    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12514            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12515        boolean dumpDetails = false;
12516        boolean dumpFullDetails = false;
12517        boolean dumpDalvik = false;
12518        boolean oomOnly = false;
12519        boolean isCompact = false;
12520        boolean localOnly = false;
12521
12522        int opti = 0;
12523        while (opti < args.length) {
12524            String opt = args[opti];
12525            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12526                break;
12527            }
12528            opti++;
12529            if ("-a".equals(opt)) {
12530                dumpDetails = true;
12531                dumpFullDetails = true;
12532                dumpDalvik = true;
12533            } else if ("-d".equals(opt)) {
12534                dumpDalvik = true;
12535            } else if ("-c".equals(opt)) {
12536                isCompact = true;
12537            } else if ("--oom".equals(opt)) {
12538                oomOnly = true;
12539            } else if ("--local".equals(opt)) {
12540                localOnly = true;
12541            } else if ("-h".equals(opt)) {
12542                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12543                pw.println("  -a: include all available information for each process.");
12544                pw.println("  -d: include dalvik details when dumping process details.");
12545                pw.println("  -c: dump in a compact machine-parseable representation.");
12546                pw.println("  --oom: only show processes organized by oom adj.");
12547                pw.println("  --local: only collect details locally, don't call process.");
12548                pw.println("If [process] is specified it can be the name or ");
12549                pw.println("pid of a specific process to dump.");
12550                return;
12551            } else {
12552                pw.println("Unknown argument: " + opt + "; use -h for help");
12553            }
12554        }
12555
12556        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12557        long uptime = SystemClock.uptimeMillis();
12558        long realtime = SystemClock.elapsedRealtime();
12559        final long[] tmpLong = new long[1];
12560
12561        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12562        if (procs == null) {
12563            // No Java processes.  Maybe they want to print a native process.
12564            if (args != null && args.length > opti
12565                    && args[opti].charAt(0) != '-') {
12566                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12567                        = new ArrayList<ProcessCpuTracker.Stats>();
12568                updateCpuStatsNow();
12569                int findPid = -1;
12570                try {
12571                    findPid = Integer.parseInt(args[opti]);
12572                } catch (NumberFormatException e) {
12573                }
12574                synchronized (mProcessCpuThread) {
12575                    final int N = mProcessCpuTracker.countStats();
12576                    for (int i=0; i<N; i++) {
12577                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12578                        if (st.pid == findPid || (st.baseName != null
12579                                && st.baseName.equals(args[opti]))) {
12580                            nativeProcs.add(st);
12581                        }
12582                    }
12583                }
12584                if (nativeProcs.size() > 0) {
12585                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12586                            isCompact);
12587                    Debug.MemoryInfo mi = null;
12588                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12589                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12590                        final int pid = r.pid;
12591                        if (!isCheckinRequest && dumpDetails) {
12592                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12593                        }
12594                        if (mi == null) {
12595                            mi = new Debug.MemoryInfo();
12596                        }
12597                        if (dumpDetails || (!brief && !oomOnly)) {
12598                            Debug.getMemoryInfo(pid, mi);
12599                        } else {
12600                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12601                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12602                        }
12603                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12604                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12605                        if (isCheckinRequest) {
12606                            pw.println();
12607                        }
12608                    }
12609                    return;
12610                }
12611            }
12612            pw.println("No process found for: " + args[opti]);
12613            return;
12614        }
12615
12616        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12617            dumpDetails = true;
12618        }
12619
12620        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12621
12622        String[] innerArgs = new String[args.length-opti];
12623        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12624
12625        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12626        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12627        long nativePss=0, dalvikPss=0, otherPss=0;
12628        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12629
12630        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12631        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12632                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12633
12634        long totalPss = 0;
12635        long cachedPss = 0;
12636
12637        Debug.MemoryInfo mi = null;
12638        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12639            final ProcessRecord r = procs.get(i);
12640            final IApplicationThread thread;
12641            final int pid;
12642            final int oomAdj;
12643            final boolean hasActivities;
12644            synchronized (this) {
12645                thread = r.thread;
12646                pid = r.pid;
12647                oomAdj = r.getSetAdjWithServices();
12648                hasActivities = r.activities.size() > 0;
12649            }
12650            if (thread != null) {
12651                if (!isCheckinRequest && dumpDetails) {
12652                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12653                }
12654                if (mi == null) {
12655                    mi = new Debug.MemoryInfo();
12656                }
12657                if (dumpDetails || (!brief && !oomOnly)) {
12658                    Debug.getMemoryInfo(pid, mi);
12659                } else {
12660                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12661                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12662                }
12663                if (dumpDetails) {
12664                    if (localOnly) {
12665                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12666                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12667                        if (isCheckinRequest) {
12668                            pw.println();
12669                        }
12670                    } else {
12671                        try {
12672                            pw.flush();
12673                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12674                                    dumpDalvik, innerArgs);
12675                        } catch (RemoteException e) {
12676                            if (!isCheckinRequest) {
12677                                pw.println("Got RemoteException!");
12678                                pw.flush();
12679                            }
12680                        }
12681                    }
12682                }
12683
12684                final long myTotalPss = mi.getTotalPss();
12685                final long myTotalUss = mi.getTotalUss();
12686
12687                synchronized (this) {
12688                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12689                        // Record this for posterity if the process has been stable.
12690                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12691                    }
12692                }
12693
12694                if (!isCheckinRequest && mi != null) {
12695                    totalPss += myTotalPss;
12696                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12697                            (hasActivities ? " / activities)" : ")"),
12698                            r.processName, myTotalPss, pid, hasActivities);
12699                    procMems.add(pssItem);
12700                    procMemsMap.put(pid, pssItem);
12701
12702                    nativePss += mi.nativePss;
12703                    dalvikPss += mi.dalvikPss;
12704                    otherPss += mi.otherPss;
12705                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12706                        long mem = mi.getOtherPss(j);
12707                        miscPss[j] += mem;
12708                        otherPss -= mem;
12709                    }
12710
12711                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12712                        cachedPss += myTotalPss;
12713                    }
12714
12715                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12716                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12717                                || oomIndex == (oomPss.length-1)) {
12718                            oomPss[oomIndex] += myTotalPss;
12719                            if (oomProcs[oomIndex] == null) {
12720                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12721                            }
12722                            oomProcs[oomIndex].add(pssItem);
12723                            break;
12724                        }
12725                    }
12726                }
12727            }
12728        }
12729
12730        long nativeProcTotalPss = 0;
12731
12732        if (!isCheckinRequest && procs.size() > 1) {
12733            // If we are showing aggregations, also look for native processes to
12734            // include so that our aggregations are more accurate.
12735            updateCpuStatsNow();
12736            synchronized (mProcessCpuThread) {
12737                final int N = mProcessCpuTracker.countStats();
12738                for (int i=0; i<N; i++) {
12739                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12740                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12741                        if (mi == null) {
12742                            mi = new Debug.MemoryInfo();
12743                        }
12744                        if (!brief && !oomOnly) {
12745                            Debug.getMemoryInfo(st.pid, mi);
12746                        } else {
12747                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12748                            mi.nativePrivateDirty = (int)tmpLong[0];
12749                        }
12750
12751                        final long myTotalPss = mi.getTotalPss();
12752                        totalPss += myTotalPss;
12753                        nativeProcTotalPss += myTotalPss;
12754
12755                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12756                                st.name, myTotalPss, st.pid, false);
12757                        procMems.add(pssItem);
12758
12759                        nativePss += mi.nativePss;
12760                        dalvikPss += mi.dalvikPss;
12761                        otherPss += mi.otherPss;
12762                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12763                            long mem = mi.getOtherPss(j);
12764                            miscPss[j] += mem;
12765                            otherPss -= mem;
12766                        }
12767                        oomPss[0] += myTotalPss;
12768                        if (oomProcs[0] == null) {
12769                            oomProcs[0] = new ArrayList<MemItem>();
12770                        }
12771                        oomProcs[0].add(pssItem);
12772                    }
12773                }
12774            }
12775
12776            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12777
12778            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12779            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12780            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12781            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12782                String label = Debug.MemoryInfo.getOtherLabel(j);
12783                catMems.add(new MemItem(label, label, miscPss[j], j));
12784            }
12785
12786            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12787            for (int j=0; j<oomPss.length; j++) {
12788                if (oomPss[j] != 0) {
12789                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12790                            : DUMP_MEM_OOM_LABEL[j];
12791                    MemItem item = new MemItem(label, label, oomPss[j],
12792                            DUMP_MEM_OOM_ADJ[j]);
12793                    item.subitems = oomProcs[j];
12794                    oomMems.add(item);
12795                }
12796            }
12797
12798            if (!brief && !oomOnly && !isCompact) {
12799                pw.println();
12800                pw.println("Total PSS by process:");
12801                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12802                pw.println();
12803            }
12804            if (!isCompact) {
12805                pw.println("Total PSS by OOM adjustment:");
12806            }
12807            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12808            if (!brief && !oomOnly) {
12809                PrintWriter out = categoryPw != null ? categoryPw : pw;
12810                if (!isCompact) {
12811                    out.println();
12812                    out.println("Total PSS by category:");
12813                }
12814                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12815            }
12816            if (!isCompact) {
12817                pw.println();
12818            }
12819            MemInfoReader memInfo = new MemInfoReader();
12820            memInfo.readMemInfo();
12821            if (nativeProcTotalPss > 0) {
12822                synchronized (this) {
12823                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
12824                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
12825                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
12826                            nativeProcTotalPss);
12827                }
12828            }
12829            if (!brief) {
12830                if (!isCompact) {
12831                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12832                    pw.print(" kB (status ");
12833                    switch (mLastMemoryLevel) {
12834                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12835                            pw.println("normal)");
12836                            break;
12837                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12838                            pw.println("moderate)");
12839                            break;
12840                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12841                            pw.println("low)");
12842                            break;
12843                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12844                            pw.println("critical)");
12845                            break;
12846                        default:
12847                            pw.print(mLastMemoryLevel);
12848                            pw.println(")");
12849                            break;
12850                    }
12851                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12852                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12853                            pw.print(cachedPss); pw.print(" cached pss + ");
12854                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12855                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12856                } else {
12857                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12858                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12859                            + memInfo.getFreeSizeKb()); pw.print(",");
12860                    pw.println(totalPss - cachedPss);
12861                }
12862            }
12863            if (!isCompact) {
12864                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12865                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12866                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12867                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12868                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12869                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12870                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12871                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12872                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12873                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12874                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12875            }
12876            if (!brief) {
12877                if (memInfo.getZramTotalSizeKb() != 0) {
12878                    if (!isCompact) {
12879                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12880                                pw.print(" kB physical used for ");
12881                                pw.print(memInfo.getSwapTotalSizeKb()
12882                                        - memInfo.getSwapFreeSizeKb());
12883                                pw.print(" kB in swap (");
12884                                pw.print(memInfo.getSwapTotalSizeKb());
12885                                pw.println(" kB total swap)");
12886                    } else {
12887                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12888                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12889                                pw.println(memInfo.getSwapFreeSizeKb());
12890                    }
12891                }
12892                final int[] SINGLE_LONG_FORMAT = new int[] {
12893                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12894                };
12895                long[] longOut = new long[1];
12896                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12897                        SINGLE_LONG_FORMAT, null, longOut, null);
12898                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12899                longOut[0] = 0;
12900                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12901                        SINGLE_LONG_FORMAT, null, longOut, null);
12902                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12903                longOut[0] = 0;
12904                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12905                        SINGLE_LONG_FORMAT, null, longOut, null);
12906                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12907                longOut[0] = 0;
12908                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12909                        SINGLE_LONG_FORMAT, null, longOut, null);
12910                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12911                if (!isCompact) {
12912                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12913                        pw.print("      KSM: "); pw.print(sharing);
12914                                pw.print(" kB saved from shared ");
12915                                pw.print(shared); pw.println(" kB");
12916                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12917                                pw.print(voltile); pw.println(" kB volatile");
12918                    }
12919                    pw.print("   Tuning: ");
12920                    pw.print(ActivityManager.staticGetMemoryClass());
12921                    pw.print(" (large ");
12922                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12923                    pw.print("), oom ");
12924                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12925                    pw.print(" kB");
12926                    pw.print(", restore limit ");
12927                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12928                    pw.print(" kB");
12929                    if (ActivityManager.isLowRamDeviceStatic()) {
12930                        pw.print(" (low-ram)");
12931                    }
12932                    if (ActivityManager.isHighEndGfx()) {
12933                        pw.print(" (high-end-gfx)");
12934                    }
12935                    pw.println();
12936                } else {
12937                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12938                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12939                    pw.println(voltile);
12940                    pw.print("tuning,");
12941                    pw.print(ActivityManager.staticGetMemoryClass());
12942                    pw.print(',');
12943                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12944                    pw.print(',');
12945                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12946                    if (ActivityManager.isLowRamDeviceStatic()) {
12947                        pw.print(",low-ram");
12948                    }
12949                    if (ActivityManager.isHighEndGfx()) {
12950                        pw.print(",high-end-gfx");
12951                    }
12952                    pw.println();
12953                }
12954            }
12955        }
12956    }
12957
12958    /**
12959     * Searches array of arguments for the specified string
12960     * @param args array of argument strings
12961     * @param value value to search for
12962     * @return true if the value is contained in the array
12963     */
12964    private static boolean scanArgs(String[] args, String value) {
12965        if (args != null) {
12966            for (String arg : args) {
12967                if (value.equals(arg)) {
12968                    return true;
12969                }
12970            }
12971        }
12972        return false;
12973    }
12974
12975    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12976            ContentProviderRecord cpr, boolean always) {
12977        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12978
12979        if (!inLaunching || always) {
12980            synchronized (cpr) {
12981                cpr.launchingApp = null;
12982                cpr.notifyAll();
12983            }
12984            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12985            String names[] = cpr.info.authority.split(";");
12986            for (int j = 0; j < names.length; j++) {
12987                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12988            }
12989        }
12990
12991        for (int i=0; i<cpr.connections.size(); i++) {
12992            ContentProviderConnection conn = cpr.connections.get(i);
12993            if (conn.waiting) {
12994                // If this connection is waiting for the provider, then we don't
12995                // need to mess with its process unless we are always removing
12996                // or for some reason the provider is not currently launching.
12997                if (inLaunching && !always) {
12998                    continue;
12999                }
13000            }
13001            ProcessRecord capp = conn.client;
13002            conn.dead = true;
13003            if (conn.stableCount > 0) {
13004                if (!capp.persistent && capp.thread != null
13005                        && capp.pid != 0
13006                        && capp.pid != MY_PID) {
13007                    killUnneededProcessLocked(capp, "depends on provider "
13008                            + cpr.name.flattenToShortString()
13009                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13010                }
13011            } else if (capp.thread != null && conn.provider.provider != null) {
13012                try {
13013                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13014                } catch (RemoteException e) {
13015                }
13016                // In the protocol here, we don't expect the client to correctly
13017                // clean up this connection, we'll just remove it.
13018                cpr.connections.remove(i);
13019                conn.client.conProviders.remove(conn);
13020            }
13021        }
13022
13023        if (inLaunching && always) {
13024            mLaunchingProviders.remove(cpr);
13025        }
13026        return inLaunching;
13027    }
13028
13029    /**
13030     * Main code for cleaning up a process when it has gone away.  This is
13031     * called both as a result of the process dying, or directly when stopping
13032     * a process when running in single process mode.
13033     */
13034    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13035            boolean restarting, boolean allowRestart, int index) {
13036        if (index >= 0) {
13037            removeLruProcessLocked(app);
13038            ProcessList.remove(app.pid);
13039        }
13040
13041        mProcessesToGc.remove(app);
13042        mPendingPssProcesses.remove(app);
13043
13044        // Dismiss any open dialogs.
13045        if (app.crashDialog != null && !app.forceCrashReport) {
13046            app.crashDialog.dismiss();
13047            app.crashDialog = null;
13048        }
13049        if (app.anrDialog != null) {
13050            app.anrDialog.dismiss();
13051            app.anrDialog = null;
13052        }
13053        if (app.waitDialog != null) {
13054            app.waitDialog.dismiss();
13055            app.waitDialog = null;
13056        }
13057
13058        app.crashing = false;
13059        app.notResponding = false;
13060
13061        app.resetPackageList(mProcessStats);
13062        app.unlinkDeathRecipient();
13063        app.makeInactive(mProcessStats);
13064        app.forcingToForeground = null;
13065        updateProcessForegroundLocked(app, false, false);
13066        app.foregroundActivities = false;
13067        app.hasShownUi = false;
13068        app.treatLikeActivity = false;
13069        app.hasAboveClient = false;
13070        app.hasClientActivities = false;
13071
13072        mServices.killServicesLocked(app, allowRestart);
13073
13074        boolean restart = false;
13075
13076        // Remove published content providers.
13077        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13078            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13079            final boolean always = app.bad || !allowRestart;
13080            if (removeDyingProviderLocked(app, cpr, always) || always) {
13081                // We left the provider in the launching list, need to
13082                // restart it.
13083                restart = true;
13084            }
13085
13086            cpr.provider = null;
13087            cpr.proc = null;
13088        }
13089        app.pubProviders.clear();
13090
13091        // Take care of any launching providers waiting for this process.
13092        if (checkAppInLaunchingProvidersLocked(app, false)) {
13093            restart = true;
13094        }
13095
13096        // Unregister from connected content providers.
13097        if (!app.conProviders.isEmpty()) {
13098            for (int i=0; i<app.conProviders.size(); i++) {
13099                ContentProviderConnection conn = app.conProviders.get(i);
13100                conn.provider.connections.remove(conn);
13101            }
13102            app.conProviders.clear();
13103        }
13104
13105        // At this point there may be remaining entries in mLaunchingProviders
13106        // where we were the only one waiting, so they are no longer of use.
13107        // Look for these and clean up if found.
13108        // XXX Commented out for now.  Trying to figure out a way to reproduce
13109        // the actual situation to identify what is actually going on.
13110        if (false) {
13111            for (int i=0; i<mLaunchingProviders.size(); i++) {
13112                ContentProviderRecord cpr = (ContentProviderRecord)
13113                        mLaunchingProviders.get(i);
13114                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13115                    synchronized (cpr) {
13116                        cpr.launchingApp = null;
13117                        cpr.notifyAll();
13118                    }
13119                }
13120            }
13121        }
13122
13123        skipCurrentReceiverLocked(app);
13124
13125        // Unregister any receivers.
13126        for (int i=app.receivers.size()-1; i>=0; i--) {
13127            removeReceiverLocked(app.receivers.valueAt(i));
13128        }
13129        app.receivers.clear();
13130
13131        // If the app is undergoing backup, tell the backup manager about it
13132        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13133            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13134                    + mBackupTarget.appInfo + " died during backup");
13135            try {
13136                IBackupManager bm = IBackupManager.Stub.asInterface(
13137                        ServiceManager.getService(Context.BACKUP_SERVICE));
13138                bm.agentDisconnected(app.info.packageName);
13139            } catch (RemoteException e) {
13140                // can't happen; backup manager is local
13141            }
13142        }
13143
13144        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13145            ProcessChangeItem item = mPendingProcessChanges.get(i);
13146            if (item.pid == app.pid) {
13147                mPendingProcessChanges.remove(i);
13148                mAvailProcessChanges.add(item);
13149            }
13150        }
13151        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13152
13153        // If the caller is restarting this app, then leave it in its
13154        // current lists and let the caller take care of it.
13155        if (restarting) {
13156            return;
13157        }
13158
13159        if (!app.persistent || app.isolated) {
13160            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13161                    "Removing non-persistent process during cleanup: " + app);
13162            mProcessNames.remove(app.processName, app.uid);
13163            mIsolatedProcesses.remove(app.uid);
13164            if (mHeavyWeightProcess == app) {
13165                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13166                        mHeavyWeightProcess.userId, 0));
13167                mHeavyWeightProcess = null;
13168            }
13169        } else if (!app.removed) {
13170            // This app is persistent, so we need to keep its record around.
13171            // If it is not already on the pending app list, add it there
13172            // and start a new process for it.
13173            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13174                mPersistentStartingProcesses.add(app);
13175                restart = true;
13176            }
13177        }
13178        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13179                "Clean-up removing on hold: " + app);
13180        mProcessesOnHold.remove(app);
13181
13182        if (app == mHomeProcess) {
13183            mHomeProcess = null;
13184        }
13185        if (app == mPreviousProcess) {
13186            mPreviousProcess = null;
13187        }
13188
13189        if (restart && !app.isolated) {
13190            // We have components that still need to be running in the
13191            // process, so re-launch it.
13192            mProcessNames.put(app.processName, app.uid, app);
13193            startProcessLocked(app, "restart", app.processName, null /* ABI override */);
13194        } else if (app.pid > 0 && app.pid != MY_PID) {
13195            // Goodbye!
13196            boolean removed;
13197            synchronized (mPidsSelfLocked) {
13198                mPidsSelfLocked.remove(app.pid);
13199                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13200            }
13201            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
13202                    app.processName, app.info.uid);
13203            if (app.isolated) {
13204                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13205            }
13206            app.setPid(0);
13207        }
13208    }
13209
13210    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13211        // Look through the content providers we are waiting to have launched,
13212        // and if any run in this process then either schedule a restart of
13213        // the process or kill the client waiting for it if this process has
13214        // gone bad.
13215        int NL = mLaunchingProviders.size();
13216        boolean restart = false;
13217        for (int i=0; i<NL; i++) {
13218            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13219            if (cpr.launchingApp == app) {
13220                if (!alwaysBad && !app.bad) {
13221                    restart = true;
13222                } else {
13223                    removeDyingProviderLocked(app, cpr, true);
13224                    // cpr should have been removed from mLaunchingProviders
13225                    NL = mLaunchingProviders.size();
13226                    i--;
13227                }
13228            }
13229        }
13230        return restart;
13231    }
13232
13233    // =========================================================
13234    // SERVICES
13235    // =========================================================
13236
13237    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13238            int flags) {
13239        enforceNotIsolatedCaller("getServices");
13240        synchronized (this) {
13241            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13242        }
13243    }
13244
13245    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13246        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13247        synchronized (this) {
13248            return mServices.getRunningServiceControlPanelLocked(name);
13249        }
13250    }
13251
13252    public ComponentName startService(IApplicationThread caller, Intent service,
13253            String resolvedType, int userId) {
13254        enforceNotIsolatedCaller("startService");
13255        // Refuse possible leaked file descriptors
13256        if (service != null && service.hasFileDescriptors() == true) {
13257            throw new IllegalArgumentException("File descriptors passed in Intent");
13258        }
13259
13260        if (DEBUG_SERVICE)
13261            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13262        synchronized(this) {
13263            final int callingPid = Binder.getCallingPid();
13264            final int callingUid = Binder.getCallingUid();
13265            final long origId = Binder.clearCallingIdentity();
13266            ComponentName res = mServices.startServiceLocked(caller, service,
13267                    resolvedType, callingPid, callingUid, userId);
13268            Binder.restoreCallingIdentity(origId);
13269            return res;
13270        }
13271    }
13272
13273    ComponentName startServiceInPackage(int uid,
13274            Intent service, String resolvedType, int userId) {
13275        synchronized(this) {
13276            if (DEBUG_SERVICE)
13277                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13278            final long origId = Binder.clearCallingIdentity();
13279            ComponentName res = mServices.startServiceLocked(null, service,
13280                    resolvedType, -1, uid, userId);
13281            Binder.restoreCallingIdentity(origId);
13282            return res;
13283        }
13284    }
13285
13286    public int stopService(IApplicationThread caller, Intent service,
13287            String resolvedType, int userId) {
13288        enforceNotIsolatedCaller("stopService");
13289        // Refuse possible leaked file descriptors
13290        if (service != null && service.hasFileDescriptors() == true) {
13291            throw new IllegalArgumentException("File descriptors passed in Intent");
13292        }
13293
13294        synchronized(this) {
13295            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13296        }
13297    }
13298
13299    public IBinder peekService(Intent service, String resolvedType) {
13300        enforceNotIsolatedCaller("peekService");
13301        // Refuse possible leaked file descriptors
13302        if (service != null && service.hasFileDescriptors() == true) {
13303            throw new IllegalArgumentException("File descriptors passed in Intent");
13304        }
13305        synchronized(this) {
13306            return mServices.peekServiceLocked(service, resolvedType);
13307        }
13308    }
13309
13310    public boolean stopServiceToken(ComponentName className, IBinder token,
13311            int startId) {
13312        synchronized(this) {
13313            return mServices.stopServiceTokenLocked(className, token, startId);
13314        }
13315    }
13316
13317    public void setServiceForeground(ComponentName className, IBinder token,
13318            int id, Notification notification, boolean removeNotification) {
13319        synchronized(this) {
13320            mServices.setServiceForegroundLocked(className, token, id, notification,
13321                    removeNotification);
13322        }
13323    }
13324
13325    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13326            boolean requireFull, String name, String callerPackage) {
13327        final int callingUserId = UserHandle.getUserId(callingUid);
13328        if (callingUserId != userId) {
13329            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13330                if ((requireFull || checkComponentPermission(
13331                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13332                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
13333                        && checkComponentPermission(INTERACT_ACROSS_USERS_FULL,
13334                                callingPid, callingUid, -1, true)
13335                                != PackageManager.PERMISSION_GRANTED) {
13336                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13337                        // In this case, they would like to just execute as their
13338                        // owner user instead of failing.
13339                        userId = callingUserId;
13340                    } else {
13341                        StringBuilder builder = new StringBuilder(128);
13342                        builder.append("Permission Denial: ");
13343                        builder.append(name);
13344                        if (callerPackage != null) {
13345                            builder.append(" from ");
13346                            builder.append(callerPackage);
13347                        }
13348                        builder.append(" asks to run as user ");
13349                        builder.append(userId);
13350                        builder.append(" but is calling from user ");
13351                        builder.append(UserHandle.getUserId(callingUid));
13352                        builder.append("; this requires ");
13353                        builder.append(INTERACT_ACROSS_USERS_FULL);
13354                        if (!requireFull) {
13355                            builder.append(" or ");
13356                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
13357                        }
13358                        String msg = builder.toString();
13359                        Slog.w(TAG, msg);
13360                        throw new SecurityException(msg);
13361                    }
13362                }
13363            }
13364            if (userId == UserHandle.USER_CURRENT
13365                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
13366                // Note that we may be accessing this outside of a lock...
13367                // shouldn't be a big deal, if this is being called outside
13368                // of a locked context there is intrinsically a race with
13369                // the value the caller will receive and someone else changing it.
13370                userId = mCurrentUserId;
13371            }
13372            if (!allowAll && userId < 0) {
13373                throw new IllegalArgumentException(
13374                        "Call does not support special user #" + userId);
13375            }
13376        }
13377        return userId;
13378    }
13379
13380    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13381            String className, int flags) {
13382        boolean result = false;
13383        // For apps that don't have pre-defined UIDs, check for permission
13384        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13385            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13386                if (ActivityManager.checkUidPermission(
13387                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13388                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13389                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13390                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13391                            + " requests FLAG_SINGLE_USER, but app does not hold "
13392                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
13393                    Slog.w(TAG, msg);
13394                    throw new SecurityException(msg);
13395                }
13396                // Permission passed
13397                result = true;
13398            }
13399        } else if ("system".equals(componentProcessName)) {
13400            result = true;
13401        } else {
13402            // App with pre-defined UID, check if it's a persistent app
13403            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13404        }
13405        if (DEBUG_MU) {
13406            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13407                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13408        }
13409        return result;
13410    }
13411
13412    /**
13413     * Checks to see if the caller is in the same app as the singleton
13414     * component, or the component is in a special app. It allows special apps
13415     * to export singleton components but prevents exporting singleton
13416     * components for regular apps.
13417     */
13418    boolean isValidSingletonCall(int callingUid, int componentUid) {
13419        int componentAppId = UserHandle.getAppId(componentUid);
13420        return UserHandle.isSameApp(callingUid, componentUid)
13421                || componentAppId == Process.SYSTEM_UID
13422                || componentAppId == Process.PHONE_UID
13423                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13424                        == PackageManager.PERMISSION_GRANTED;
13425    }
13426
13427    public int bindService(IApplicationThread caller, IBinder token,
13428            Intent service, String resolvedType,
13429            IServiceConnection connection, int flags, int userId) {
13430        enforceNotIsolatedCaller("bindService");
13431        // Refuse possible leaked file descriptors
13432        if (service != null && service.hasFileDescriptors() == true) {
13433            throw new IllegalArgumentException("File descriptors passed in Intent");
13434        }
13435
13436        synchronized(this) {
13437            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13438                    connection, flags, userId);
13439        }
13440    }
13441
13442    public boolean unbindService(IServiceConnection connection) {
13443        synchronized (this) {
13444            return mServices.unbindServiceLocked(connection);
13445        }
13446    }
13447
13448    public void publishService(IBinder token, Intent intent, IBinder service) {
13449        // Refuse possible leaked file descriptors
13450        if (intent != null && intent.hasFileDescriptors() == true) {
13451            throw new IllegalArgumentException("File descriptors passed in Intent");
13452        }
13453
13454        synchronized(this) {
13455            if (!(token instanceof ServiceRecord)) {
13456                throw new IllegalArgumentException("Invalid service token");
13457            }
13458            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13459        }
13460    }
13461
13462    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13463        // Refuse possible leaked file descriptors
13464        if (intent != null && intent.hasFileDescriptors() == true) {
13465            throw new IllegalArgumentException("File descriptors passed in Intent");
13466        }
13467
13468        synchronized(this) {
13469            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13470        }
13471    }
13472
13473    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13474        synchronized(this) {
13475            if (!(token instanceof ServiceRecord)) {
13476                throw new IllegalArgumentException("Invalid service token");
13477            }
13478            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13479        }
13480    }
13481
13482    // =========================================================
13483    // BACKUP AND RESTORE
13484    // =========================================================
13485
13486    // Cause the target app to be launched if necessary and its backup agent
13487    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13488    // activity manager to announce its creation.
13489    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13490        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13491        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
13492
13493        synchronized(this) {
13494            // !!! TODO: currently no check here that we're already bound
13495            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13496            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13497            synchronized (stats) {
13498                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13499            }
13500
13501            // Backup agent is now in use, its package can't be stopped.
13502            try {
13503                AppGlobals.getPackageManager().setPackageStoppedState(
13504                        app.packageName, false, UserHandle.getUserId(app.uid));
13505            } catch (RemoteException e) {
13506            } catch (IllegalArgumentException e) {
13507                Slog.w(TAG, "Failed trying to unstop package "
13508                        + app.packageName + ": " + e);
13509            }
13510
13511            BackupRecord r = new BackupRecord(ss, app, backupMode);
13512            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13513                    ? new ComponentName(app.packageName, app.backupAgentName)
13514                    : new ComponentName("android", "FullBackupAgent");
13515            // startProcessLocked() returns existing proc's record if it's already running
13516            ProcessRecord proc = startProcessLocked(app.processName, app,
13517                    false, 0, "backup", hostingName, false, false, false);
13518            if (proc == null) {
13519                Slog.e(TAG, "Unable to start backup agent process " + r);
13520                return false;
13521            }
13522
13523            r.app = proc;
13524            mBackupTarget = r;
13525            mBackupAppName = app.packageName;
13526
13527            // Try not to kill the process during backup
13528            updateOomAdjLocked(proc);
13529
13530            // If the process is already attached, schedule the creation of the backup agent now.
13531            // If it is not yet live, this will be done when it attaches to the framework.
13532            if (proc.thread != null) {
13533                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13534                try {
13535                    proc.thread.scheduleCreateBackupAgent(app,
13536                            compatibilityInfoForPackageLocked(app), backupMode);
13537                } catch (RemoteException e) {
13538                    // Will time out on the backup manager side
13539                }
13540            } else {
13541                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13542            }
13543            // Invariants: at this point, the target app process exists and the application
13544            // is either already running or in the process of coming up.  mBackupTarget and
13545            // mBackupAppName describe the app, so that when it binds back to the AM we
13546            // know that it's scheduled for a backup-agent operation.
13547        }
13548
13549        return true;
13550    }
13551
13552    @Override
13553    public void clearPendingBackup() {
13554        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13555        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13556
13557        synchronized (this) {
13558            mBackupTarget = null;
13559            mBackupAppName = null;
13560        }
13561    }
13562
13563    // A backup agent has just come up
13564    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13565        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13566                + " = " + agent);
13567
13568        synchronized(this) {
13569            if (!agentPackageName.equals(mBackupAppName)) {
13570                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13571                return;
13572            }
13573        }
13574
13575        long oldIdent = Binder.clearCallingIdentity();
13576        try {
13577            IBackupManager bm = IBackupManager.Stub.asInterface(
13578                    ServiceManager.getService(Context.BACKUP_SERVICE));
13579            bm.agentConnected(agentPackageName, agent);
13580        } catch (RemoteException e) {
13581            // can't happen; the backup manager service is local
13582        } catch (Exception e) {
13583            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13584            e.printStackTrace();
13585        } finally {
13586            Binder.restoreCallingIdentity(oldIdent);
13587        }
13588    }
13589
13590    // done with this agent
13591    public void unbindBackupAgent(ApplicationInfo appInfo) {
13592        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13593        if (appInfo == null) {
13594            Slog.w(TAG, "unbind backup agent for null app");
13595            return;
13596        }
13597
13598        synchronized(this) {
13599            try {
13600                if (mBackupAppName == null) {
13601                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13602                    return;
13603                }
13604
13605                if (!mBackupAppName.equals(appInfo.packageName)) {
13606                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13607                    return;
13608                }
13609
13610                // Not backing this app up any more; reset its OOM adjustment
13611                final ProcessRecord proc = mBackupTarget.app;
13612                updateOomAdjLocked(proc);
13613
13614                // If the app crashed during backup, 'thread' will be null here
13615                if (proc.thread != null) {
13616                    try {
13617                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13618                                compatibilityInfoForPackageLocked(appInfo));
13619                    } catch (Exception e) {
13620                        Slog.e(TAG, "Exception when unbinding backup agent:");
13621                        e.printStackTrace();
13622                    }
13623                }
13624            } finally {
13625                mBackupTarget = null;
13626                mBackupAppName = null;
13627            }
13628        }
13629    }
13630    // =========================================================
13631    // BROADCASTS
13632    // =========================================================
13633
13634    private final List getStickiesLocked(String action, IntentFilter filter,
13635            List cur, int userId) {
13636        final ContentResolver resolver = mContext.getContentResolver();
13637        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13638        if (stickies == null) {
13639            return cur;
13640        }
13641        final ArrayList<Intent> list = stickies.get(action);
13642        if (list == null) {
13643            return cur;
13644        }
13645        int N = list.size();
13646        for (int i=0; i<N; i++) {
13647            Intent intent = list.get(i);
13648            if (filter.match(resolver, intent, true, TAG) >= 0) {
13649                if (cur == null) {
13650                    cur = new ArrayList<Intent>();
13651                }
13652                cur.add(intent);
13653            }
13654        }
13655        return cur;
13656    }
13657
13658    boolean isPendingBroadcastProcessLocked(int pid) {
13659        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13660                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13661    }
13662
13663    void skipPendingBroadcastLocked(int pid) {
13664            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13665            for (BroadcastQueue queue : mBroadcastQueues) {
13666                queue.skipPendingBroadcastLocked(pid);
13667            }
13668    }
13669
13670    // The app just attached; send any pending broadcasts that it should receive
13671    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13672        boolean didSomething = false;
13673        for (BroadcastQueue queue : mBroadcastQueues) {
13674            didSomething |= queue.sendPendingBroadcastsLocked(app);
13675        }
13676        return didSomething;
13677    }
13678
13679    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13680            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13681        enforceNotIsolatedCaller("registerReceiver");
13682        int callingUid;
13683        int callingPid;
13684        synchronized(this) {
13685            ProcessRecord callerApp = null;
13686            if (caller != null) {
13687                callerApp = getRecordForAppLocked(caller);
13688                if (callerApp == null) {
13689                    throw new SecurityException(
13690                            "Unable to find app for caller " + caller
13691                            + " (pid=" + Binder.getCallingPid()
13692                            + ") when registering receiver " + receiver);
13693                }
13694                if (callerApp.info.uid != Process.SYSTEM_UID &&
13695                        !callerApp.pkgList.containsKey(callerPackage) &&
13696                        !"android".equals(callerPackage)) {
13697                    throw new SecurityException("Given caller package " + callerPackage
13698                            + " is not running in process " + callerApp);
13699                }
13700                callingUid = callerApp.info.uid;
13701                callingPid = callerApp.pid;
13702            } else {
13703                callerPackage = null;
13704                callingUid = Binder.getCallingUid();
13705                callingPid = Binder.getCallingPid();
13706            }
13707
13708            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13709                    true, true, "registerReceiver", callerPackage);
13710
13711            List allSticky = null;
13712
13713            // Look for any matching sticky broadcasts...
13714            Iterator actions = filter.actionsIterator();
13715            if (actions != null) {
13716                while (actions.hasNext()) {
13717                    String action = (String)actions.next();
13718                    allSticky = getStickiesLocked(action, filter, allSticky,
13719                            UserHandle.USER_ALL);
13720                    allSticky = getStickiesLocked(action, filter, allSticky,
13721                            UserHandle.getUserId(callingUid));
13722                }
13723            } else {
13724                allSticky = getStickiesLocked(null, filter, allSticky,
13725                        UserHandle.USER_ALL);
13726                allSticky = getStickiesLocked(null, filter, allSticky,
13727                        UserHandle.getUserId(callingUid));
13728            }
13729
13730            // The first sticky in the list is returned directly back to
13731            // the client.
13732            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13733
13734            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13735                    + ": " + sticky);
13736
13737            if (receiver == null) {
13738                return sticky;
13739            }
13740
13741            ReceiverList rl
13742                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13743            if (rl == null) {
13744                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13745                        userId, receiver);
13746                if (rl.app != null) {
13747                    rl.app.receivers.add(rl);
13748                } else {
13749                    try {
13750                        receiver.asBinder().linkToDeath(rl, 0);
13751                    } catch (RemoteException e) {
13752                        return sticky;
13753                    }
13754                    rl.linkedToDeath = true;
13755                }
13756                mRegisteredReceivers.put(receiver.asBinder(), rl);
13757            } else if (rl.uid != callingUid) {
13758                throw new IllegalArgumentException(
13759                        "Receiver requested to register for uid " + callingUid
13760                        + " was previously registered for uid " + rl.uid);
13761            } else if (rl.pid != callingPid) {
13762                throw new IllegalArgumentException(
13763                        "Receiver requested to register for pid " + callingPid
13764                        + " was previously registered for pid " + rl.pid);
13765            } else if (rl.userId != userId) {
13766                throw new IllegalArgumentException(
13767                        "Receiver requested to register for user " + userId
13768                        + " was previously registered for user " + rl.userId);
13769            }
13770            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13771                    permission, callingUid, userId);
13772            rl.add(bf);
13773            if (!bf.debugCheck()) {
13774                Slog.w(TAG, "==> For Dynamic broadast");
13775            }
13776            mReceiverResolver.addFilter(bf);
13777
13778            // Enqueue broadcasts for all existing stickies that match
13779            // this filter.
13780            if (allSticky != null) {
13781                ArrayList receivers = new ArrayList();
13782                receivers.add(bf);
13783
13784                int N = allSticky.size();
13785                for (int i=0; i<N; i++) {
13786                    Intent intent = (Intent)allSticky.get(i);
13787                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13788                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13789                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13790                            null, null, false, true, true, -1);
13791                    queue.enqueueParallelBroadcastLocked(r);
13792                    queue.scheduleBroadcastsLocked();
13793                }
13794            }
13795
13796            return sticky;
13797        }
13798    }
13799
13800    public void unregisterReceiver(IIntentReceiver receiver) {
13801        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13802
13803        final long origId = Binder.clearCallingIdentity();
13804        try {
13805            boolean doTrim = false;
13806
13807            synchronized(this) {
13808                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13809                if (rl != null) {
13810                    if (rl.curBroadcast != null) {
13811                        BroadcastRecord r = rl.curBroadcast;
13812                        final boolean doNext = finishReceiverLocked(
13813                                receiver.asBinder(), r.resultCode, r.resultData,
13814                                r.resultExtras, r.resultAbort);
13815                        if (doNext) {
13816                            doTrim = true;
13817                            r.queue.processNextBroadcast(false);
13818                        }
13819                    }
13820
13821                    if (rl.app != null) {
13822                        rl.app.receivers.remove(rl);
13823                    }
13824                    removeReceiverLocked(rl);
13825                    if (rl.linkedToDeath) {
13826                        rl.linkedToDeath = false;
13827                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13828                    }
13829                }
13830            }
13831
13832            // If we actually concluded any broadcasts, we might now be able
13833            // to trim the recipients' apps from our working set
13834            if (doTrim) {
13835                trimApplications();
13836                return;
13837            }
13838
13839        } finally {
13840            Binder.restoreCallingIdentity(origId);
13841        }
13842    }
13843
13844    void removeReceiverLocked(ReceiverList rl) {
13845        mRegisteredReceivers.remove(rl.receiver.asBinder());
13846        int N = rl.size();
13847        for (int i=0; i<N; i++) {
13848            mReceiverResolver.removeFilter(rl.get(i));
13849        }
13850    }
13851
13852    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13853        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13854            ProcessRecord r = mLruProcesses.get(i);
13855            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13856                try {
13857                    r.thread.dispatchPackageBroadcast(cmd, packages);
13858                } catch (RemoteException ex) {
13859                }
13860            }
13861        }
13862    }
13863
13864    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13865            int[] users) {
13866        List<ResolveInfo> receivers = null;
13867        try {
13868            HashSet<ComponentName> singleUserReceivers = null;
13869            boolean scannedFirstReceivers = false;
13870            for (int user : users) {
13871                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13872                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13873                if (user != 0 && newReceivers != null) {
13874                    // If this is not the primary user, we need to check for
13875                    // any receivers that should be filtered out.
13876                    for (int i=0; i<newReceivers.size(); i++) {
13877                        ResolveInfo ri = newReceivers.get(i);
13878                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13879                            newReceivers.remove(i);
13880                            i--;
13881                        }
13882                    }
13883                }
13884                if (newReceivers != null && newReceivers.size() == 0) {
13885                    newReceivers = null;
13886                }
13887                if (receivers == null) {
13888                    receivers = newReceivers;
13889                } else if (newReceivers != null) {
13890                    // We need to concatenate the additional receivers
13891                    // found with what we have do far.  This would be easy,
13892                    // but we also need to de-dup any receivers that are
13893                    // singleUser.
13894                    if (!scannedFirstReceivers) {
13895                        // Collect any single user receivers we had already retrieved.
13896                        scannedFirstReceivers = true;
13897                        for (int i=0; i<receivers.size(); i++) {
13898                            ResolveInfo ri = receivers.get(i);
13899                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13900                                ComponentName cn = new ComponentName(
13901                                        ri.activityInfo.packageName, ri.activityInfo.name);
13902                                if (singleUserReceivers == null) {
13903                                    singleUserReceivers = new HashSet<ComponentName>();
13904                                }
13905                                singleUserReceivers.add(cn);
13906                            }
13907                        }
13908                    }
13909                    // Add the new results to the existing results, tracking
13910                    // and de-dupping single user receivers.
13911                    for (int i=0; i<newReceivers.size(); i++) {
13912                        ResolveInfo ri = newReceivers.get(i);
13913                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13914                            ComponentName cn = new ComponentName(
13915                                    ri.activityInfo.packageName, ri.activityInfo.name);
13916                            if (singleUserReceivers == null) {
13917                                singleUserReceivers = new HashSet<ComponentName>();
13918                            }
13919                            if (!singleUserReceivers.contains(cn)) {
13920                                singleUserReceivers.add(cn);
13921                                receivers.add(ri);
13922                            }
13923                        } else {
13924                            receivers.add(ri);
13925                        }
13926                    }
13927                }
13928            }
13929        } catch (RemoteException ex) {
13930            // pm is in same process, this will never happen.
13931        }
13932        return receivers;
13933    }
13934
13935    private final int broadcastIntentLocked(ProcessRecord callerApp,
13936            String callerPackage, Intent intent, String resolvedType,
13937            IIntentReceiver resultTo, int resultCode, String resultData,
13938            Bundle map, String requiredPermission, int appOp,
13939            boolean ordered, boolean sticky, int callingPid, int callingUid,
13940            int userId) {
13941        intent = new Intent(intent);
13942
13943        // By default broadcasts do not go to stopped apps.
13944        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13945
13946        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13947            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13948            + " ordered=" + ordered + " userid=" + userId);
13949        if ((resultTo != null) && !ordered) {
13950            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13951        }
13952
13953        userId = handleIncomingUser(callingPid, callingUid, userId,
13954                true, false, "broadcast", callerPackage);
13955
13956        // Make sure that the user who is receiving this broadcast is started.
13957        // If not, we will just skip it.
13958        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13959            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13960                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13961                Slog.w(TAG, "Skipping broadcast of " + intent
13962                        + ": user " + userId + " is stopped");
13963                return ActivityManager.BROADCAST_SUCCESS;
13964            }
13965        }
13966
13967        /*
13968         * Prevent non-system code (defined here to be non-persistent
13969         * processes) from sending protected broadcasts.
13970         */
13971        int callingAppId = UserHandle.getAppId(callingUid);
13972        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13973                || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
13974                || callingUid == 0) {
13975            // Always okay.
13976        } else if (callerApp == null || !callerApp.persistent) {
13977            try {
13978                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13979                        intent.getAction())) {
13980                    String msg = "Permission Denial: not allowed to send broadcast "
13981                            + intent.getAction() + " from pid="
13982                            + callingPid + ", uid=" + callingUid;
13983                    Slog.w(TAG, msg);
13984                    throw new SecurityException(msg);
13985                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13986                    // Special case for compatibility: we don't want apps to send this,
13987                    // but historically it has not been protected and apps may be using it
13988                    // to poke their own app widget.  So, instead of making it protected,
13989                    // just limit it to the caller.
13990                    if (callerApp == null) {
13991                        String msg = "Permission Denial: not allowed to send broadcast "
13992                                + intent.getAction() + " from unknown caller.";
13993                        Slog.w(TAG, msg);
13994                        throw new SecurityException(msg);
13995                    } else if (intent.getComponent() != null) {
13996                        // They are good enough to send to an explicit component...  verify
13997                        // it is being sent to the calling app.
13998                        if (!intent.getComponent().getPackageName().equals(
13999                                callerApp.info.packageName)) {
14000                            String msg = "Permission Denial: not allowed to send broadcast "
14001                                    + intent.getAction() + " to "
14002                                    + intent.getComponent().getPackageName() + " from "
14003                                    + callerApp.info.packageName;
14004                            Slog.w(TAG, msg);
14005                            throw new SecurityException(msg);
14006                        }
14007                    } else {
14008                        // Limit broadcast to their own package.
14009                        intent.setPackage(callerApp.info.packageName);
14010                    }
14011                }
14012            } catch (RemoteException e) {
14013                Slog.w(TAG, "Remote exception", e);
14014                return ActivityManager.BROADCAST_SUCCESS;
14015            }
14016        }
14017
14018        // Handle special intents: if this broadcast is from the package
14019        // manager about a package being removed, we need to remove all of
14020        // its activities from the history stack.
14021        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14022                intent.getAction());
14023        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14024                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14025                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14026                || uidRemoved) {
14027            if (checkComponentPermission(
14028                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14029                    callingPid, callingUid, -1, true)
14030                    == PackageManager.PERMISSION_GRANTED) {
14031                if (uidRemoved) {
14032                    final Bundle intentExtras = intent.getExtras();
14033                    final int uid = intentExtras != null
14034                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14035                    if (uid >= 0) {
14036                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14037                        synchronized (bs) {
14038                            bs.removeUidStatsLocked(uid);
14039                        }
14040                        mAppOpsService.uidRemoved(uid);
14041                    }
14042                } else {
14043                    // If resources are unavailable just force stop all
14044                    // those packages and flush the attribute cache as well.
14045                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14046                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14047                        if (list != null && (list.length > 0)) {
14048                            for (String pkg : list) {
14049                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14050                                        "storage unmount");
14051                            }
14052                            sendPackageBroadcastLocked(
14053                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14054                        }
14055                    } else {
14056                        Uri data = intent.getData();
14057                        String ssp;
14058                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14059                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14060                                    intent.getAction());
14061                            boolean fullUninstall = removed &&
14062                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14063                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14064                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14065                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14066                                        false, fullUninstall, userId,
14067                                        removed ? "pkg removed" : "pkg changed");
14068                            }
14069                            if (removed) {
14070                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14071                                        new String[] {ssp}, userId);
14072                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14073                                    mAppOpsService.packageRemoved(
14074                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14075
14076                                    // Remove all permissions granted from/to this package
14077                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14078                                }
14079                            }
14080                        }
14081                    }
14082                }
14083            } else {
14084                String msg = "Permission Denial: " + intent.getAction()
14085                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14086                        + ", uid=" + callingUid + ")"
14087                        + " requires "
14088                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14089                Slog.w(TAG, msg);
14090                throw new SecurityException(msg);
14091            }
14092
14093        // Special case for adding a package: by default turn on compatibility
14094        // mode.
14095        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14096            Uri data = intent.getData();
14097            String ssp;
14098            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14099                mCompatModePackages.handlePackageAddedLocked(ssp,
14100                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14101            }
14102        }
14103
14104        /*
14105         * If this is the time zone changed action, queue up a message that will reset the timezone
14106         * of all currently running processes. This message will get queued up before the broadcast
14107         * happens.
14108         */
14109        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14110            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14111        }
14112
14113        /*
14114         * If the user set the time, let all running processes know.
14115         */
14116        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14117            final int is24Hour = intent.getBooleanExtra(
14118                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14119            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14120        }
14121
14122        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14123            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14124        }
14125
14126        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14127            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14128            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14129        }
14130
14131        // Add to the sticky list if requested.
14132        if (sticky) {
14133            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14134                    callingPid, callingUid)
14135                    != PackageManager.PERMISSION_GRANTED) {
14136                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14137                        + callingPid + ", uid=" + callingUid
14138                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14139                Slog.w(TAG, msg);
14140                throw new SecurityException(msg);
14141            }
14142            if (requiredPermission != null) {
14143                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14144                        + " and enforce permission " + requiredPermission);
14145                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14146            }
14147            if (intent.getComponent() != null) {
14148                throw new SecurityException(
14149                        "Sticky broadcasts can't target a specific component");
14150            }
14151            // We use userId directly here, since the "all" target is maintained
14152            // as a separate set of sticky broadcasts.
14153            if (userId != UserHandle.USER_ALL) {
14154                // But first, if this is not a broadcast to all users, then
14155                // make sure it doesn't conflict with an existing broadcast to
14156                // all users.
14157                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14158                        UserHandle.USER_ALL);
14159                if (stickies != null) {
14160                    ArrayList<Intent> list = stickies.get(intent.getAction());
14161                    if (list != null) {
14162                        int N = list.size();
14163                        int i;
14164                        for (i=0; i<N; i++) {
14165                            if (intent.filterEquals(list.get(i))) {
14166                                throw new IllegalArgumentException(
14167                                        "Sticky broadcast " + intent + " for user "
14168                                        + userId + " conflicts with existing global broadcast");
14169                            }
14170                        }
14171                    }
14172                }
14173            }
14174            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14175            if (stickies == null) {
14176                stickies = new ArrayMap<String, ArrayList<Intent>>();
14177                mStickyBroadcasts.put(userId, stickies);
14178            }
14179            ArrayList<Intent> list = stickies.get(intent.getAction());
14180            if (list == null) {
14181                list = new ArrayList<Intent>();
14182                stickies.put(intent.getAction(), list);
14183            }
14184            int N = list.size();
14185            int i;
14186            for (i=0; i<N; i++) {
14187                if (intent.filterEquals(list.get(i))) {
14188                    // This sticky already exists, replace it.
14189                    list.set(i, new Intent(intent));
14190                    break;
14191                }
14192            }
14193            if (i >= N) {
14194                list.add(new Intent(intent));
14195            }
14196        }
14197
14198        int[] users;
14199        if (userId == UserHandle.USER_ALL) {
14200            // Caller wants broadcast to go to all started users.
14201            users = mStartedUserArray;
14202        } else {
14203            // Caller wants broadcast to go to one specific user.
14204            users = new int[] {userId};
14205        }
14206
14207        // Figure out who all will receive this broadcast.
14208        List receivers = null;
14209        List<BroadcastFilter> registeredReceivers = null;
14210        // Need to resolve the intent to interested receivers...
14211        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14212                 == 0) {
14213            receivers = collectReceiverComponents(intent, resolvedType, users);
14214        }
14215        if (intent.getComponent() == null) {
14216            registeredReceivers = mReceiverResolver.queryIntent(intent,
14217                    resolvedType, false, userId);
14218        }
14219
14220        final boolean replacePending =
14221                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14222
14223        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14224                + " replacePending=" + replacePending);
14225
14226        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14227        if (!ordered && NR > 0) {
14228            // If we are not serializing this broadcast, then send the
14229            // registered receivers separately so they don't wait for the
14230            // components to be launched.
14231            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14232            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14233                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14234                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14235                    ordered, sticky, false, userId);
14236            if (DEBUG_BROADCAST) Slog.v(
14237                    TAG, "Enqueueing parallel broadcast " + r);
14238            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14239            if (!replaced) {
14240                queue.enqueueParallelBroadcastLocked(r);
14241                queue.scheduleBroadcastsLocked();
14242            }
14243            registeredReceivers = null;
14244            NR = 0;
14245        }
14246
14247        // Merge into one list.
14248        int ir = 0;
14249        if (receivers != null) {
14250            // A special case for PACKAGE_ADDED: do not allow the package
14251            // being added to see this broadcast.  This prevents them from
14252            // using this as a back door to get run as soon as they are
14253            // installed.  Maybe in the future we want to have a special install
14254            // broadcast or such for apps, but we'd like to deliberately make
14255            // this decision.
14256            String skipPackages[] = null;
14257            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14258                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14259                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14260                Uri data = intent.getData();
14261                if (data != null) {
14262                    String pkgName = data.getSchemeSpecificPart();
14263                    if (pkgName != null) {
14264                        skipPackages = new String[] { pkgName };
14265                    }
14266                }
14267            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14268                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14269            }
14270            if (skipPackages != null && (skipPackages.length > 0)) {
14271                for (String skipPackage : skipPackages) {
14272                    if (skipPackage != null) {
14273                        int NT = receivers.size();
14274                        for (int it=0; it<NT; it++) {
14275                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14276                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14277                                receivers.remove(it);
14278                                it--;
14279                                NT--;
14280                            }
14281                        }
14282                    }
14283                }
14284            }
14285
14286            int NT = receivers != null ? receivers.size() : 0;
14287            int it = 0;
14288            ResolveInfo curt = null;
14289            BroadcastFilter curr = null;
14290            while (it < NT && ir < NR) {
14291                if (curt == null) {
14292                    curt = (ResolveInfo)receivers.get(it);
14293                }
14294                if (curr == null) {
14295                    curr = registeredReceivers.get(ir);
14296                }
14297                if (curr.getPriority() >= curt.priority) {
14298                    // Insert this broadcast record into the final list.
14299                    receivers.add(it, curr);
14300                    ir++;
14301                    curr = null;
14302                    it++;
14303                    NT++;
14304                } else {
14305                    // Skip to the next ResolveInfo in the final list.
14306                    it++;
14307                    curt = null;
14308                }
14309            }
14310        }
14311        while (ir < NR) {
14312            if (receivers == null) {
14313                receivers = new ArrayList();
14314            }
14315            receivers.add(registeredReceivers.get(ir));
14316            ir++;
14317        }
14318
14319        if ((receivers != null && receivers.size() > 0)
14320                || resultTo != null) {
14321            BroadcastQueue queue = broadcastQueueForIntent(intent);
14322            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14323                    callerPackage, callingPid, callingUid, resolvedType,
14324                    requiredPermission, appOp, receivers, resultTo, resultCode,
14325                    resultData, map, ordered, sticky, false, userId);
14326            if (DEBUG_BROADCAST) Slog.v(
14327                    TAG, "Enqueueing ordered broadcast " + r
14328                    + ": prev had " + queue.mOrderedBroadcasts.size());
14329            if (DEBUG_BROADCAST) {
14330                int seq = r.intent.getIntExtra("seq", -1);
14331                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14332            }
14333            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14334            if (!replaced) {
14335                queue.enqueueOrderedBroadcastLocked(r);
14336                queue.scheduleBroadcastsLocked();
14337            }
14338        }
14339
14340        return ActivityManager.BROADCAST_SUCCESS;
14341    }
14342
14343    final Intent verifyBroadcastLocked(Intent intent) {
14344        // Refuse possible leaked file descriptors
14345        if (intent != null && intent.hasFileDescriptors() == true) {
14346            throw new IllegalArgumentException("File descriptors passed in Intent");
14347        }
14348
14349        int flags = intent.getFlags();
14350
14351        if (!mProcessesReady) {
14352            // if the caller really truly claims to know what they're doing, go
14353            // ahead and allow the broadcast without launching any receivers
14354            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14355                intent = new Intent(intent);
14356                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14357            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14358                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14359                        + " before boot completion");
14360                throw new IllegalStateException("Cannot broadcast before boot completed");
14361            }
14362        }
14363
14364        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14365            throw new IllegalArgumentException(
14366                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14367        }
14368
14369        return intent;
14370    }
14371
14372    public final int broadcastIntent(IApplicationThread caller,
14373            Intent intent, String resolvedType, IIntentReceiver resultTo,
14374            int resultCode, String resultData, Bundle map,
14375            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14376        enforceNotIsolatedCaller("broadcastIntent");
14377        synchronized(this) {
14378            intent = verifyBroadcastLocked(intent);
14379
14380            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14381            final int callingPid = Binder.getCallingPid();
14382            final int callingUid = Binder.getCallingUid();
14383            final long origId = Binder.clearCallingIdentity();
14384            int res = broadcastIntentLocked(callerApp,
14385                    callerApp != null ? callerApp.info.packageName : null,
14386                    intent, resolvedType, resultTo,
14387                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14388                    callingPid, callingUid, userId);
14389            Binder.restoreCallingIdentity(origId);
14390            return res;
14391        }
14392    }
14393
14394    int broadcastIntentInPackage(String packageName, int uid,
14395            Intent intent, String resolvedType, IIntentReceiver resultTo,
14396            int resultCode, String resultData, Bundle map,
14397            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14398        synchronized(this) {
14399            intent = verifyBroadcastLocked(intent);
14400
14401            final long origId = Binder.clearCallingIdentity();
14402            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14403                    resultTo, resultCode, resultData, map, requiredPermission,
14404                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14405            Binder.restoreCallingIdentity(origId);
14406            return res;
14407        }
14408    }
14409
14410    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14411        // Refuse possible leaked file descriptors
14412        if (intent != null && intent.hasFileDescriptors() == true) {
14413            throw new IllegalArgumentException("File descriptors passed in Intent");
14414        }
14415
14416        userId = handleIncomingUser(Binder.getCallingPid(),
14417                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
14418
14419        synchronized(this) {
14420            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14421                    != PackageManager.PERMISSION_GRANTED) {
14422                String msg = "Permission Denial: unbroadcastIntent() from pid="
14423                        + Binder.getCallingPid()
14424                        + ", uid=" + Binder.getCallingUid()
14425                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14426                Slog.w(TAG, msg);
14427                throw new SecurityException(msg);
14428            }
14429            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14430            if (stickies != null) {
14431                ArrayList<Intent> list = stickies.get(intent.getAction());
14432                if (list != null) {
14433                    int N = list.size();
14434                    int i;
14435                    for (i=0; i<N; i++) {
14436                        if (intent.filterEquals(list.get(i))) {
14437                            list.remove(i);
14438                            break;
14439                        }
14440                    }
14441                    if (list.size() <= 0) {
14442                        stickies.remove(intent.getAction());
14443                    }
14444                }
14445                if (stickies.size() <= 0) {
14446                    mStickyBroadcasts.remove(userId);
14447                }
14448            }
14449        }
14450    }
14451
14452    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14453            String resultData, Bundle resultExtras, boolean resultAbort) {
14454        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14455        if (r == null) {
14456            Slog.w(TAG, "finishReceiver called but not found on queue");
14457            return false;
14458        }
14459
14460        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14461    }
14462
14463    void backgroundServicesFinishedLocked(int userId) {
14464        for (BroadcastQueue queue : mBroadcastQueues) {
14465            queue.backgroundServicesFinishedLocked(userId);
14466        }
14467    }
14468
14469    public void finishReceiver(IBinder who, int resultCode, String resultData,
14470            Bundle resultExtras, boolean resultAbort) {
14471        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14472
14473        // Refuse possible leaked file descriptors
14474        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14475            throw new IllegalArgumentException("File descriptors passed in Bundle");
14476        }
14477
14478        final long origId = Binder.clearCallingIdentity();
14479        try {
14480            boolean doNext = false;
14481            BroadcastRecord r;
14482
14483            synchronized(this) {
14484                r = broadcastRecordForReceiverLocked(who);
14485                if (r != null) {
14486                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14487                        resultData, resultExtras, resultAbort, true);
14488                }
14489            }
14490
14491            if (doNext) {
14492                r.queue.processNextBroadcast(false);
14493            }
14494            trimApplications();
14495        } finally {
14496            Binder.restoreCallingIdentity(origId);
14497        }
14498    }
14499
14500    // =========================================================
14501    // INSTRUMENTATION
14502    // =========================================================
14503
14504    public boolean startInstrumentation(ComponentName className,
14505            String profileFile, int flags, Bundle arguments,
14506            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14507            int userId, String abiOverride) {
14508        enforceNotIsolatedCaller("startInstrumentation");
14509        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14510                userId, false, true, "startInstrumentation", null);
14511        // Refuse possible leaked file descriptors
14512        if (arguments != null && arguments.hasFileDescriptors()) {
14513            throw new IllegalArgumentException("File descriptors passed in Bundle");
14514        }
14515
14516        synchronized(this) {
14517            InstrumentationInfo ii = null;
14518            ApplicationInfo ai = null;
14519            try {
14520                ii = mContext.getPackageManager().getInstrumentationInfo(
14521                    className, STOCK_PM_FLAGS);
14522                ai = AppGlobals.getPackageManager().getApplicationInfo(
14523                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14524            } catch (PackageManager.NameNotFoundException e) {
14525            } catch (RemoteException e) {
14526            }
14527            if (ii == null) {
14528                reportStartInstrumentationFailure(watcher, className,
14529                        "Unable to find instrumentation info for: " + className);
14530                return false;
14531            }
14532            if (ai == null) {
14533                reportStartInstrumentationFailure(watcher, className,
14534                        "Unable to find instrumentation target package: " + ii.targetPackage);
14535                return false;
14536            }
14537
14538            int match = mContext.getPackageManager().checkSignatures(
14539                    ii.targetPackage, ii.packageName);
14540            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14541                String msg = "Permission Denial: starting instrumentation "
14542                        + className + " from pid="
14543                        + Binder.getCallingPid()
14544                        + ", uid=" + Binder.getCallingPid()
14545                        + " not allowed because package " + ii.packageName
14546                        + " does not have a signature matching the target "
14547                        + ii.targetPackage;
14548                reportStartInstrumentationFailure(watcher, className, msg);
14549                throw new SecurityException(msg);
14550            }
14551
14552            final long origId = Binder.clearCallingIdentity();
14553            // Instrumentation can kill and relaunch even persistent processes
14554            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14555                    "start instr");
14556            ProcessRecord app = addAppLocked(ai, false, abiOverride);
14557            app.instrumentationClass = className;
14558            app.instrumentationInfo = ai;
14559            app.instrumentationProfileFile = profileFile;
14560            app.instrumentationArguments = arguments;
14561            app.instrumentationWatcher = watcher;
14562            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14563            app.instrumentationResultClass = className;
14564            Binder.restoreCallingIdentity(origId);
14565        }
14566
14567        return true;
14568    }
14569
14570    /**
14571     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14572     * error to the logs, but if somebody is watching, send the report there too.  This enables
14573     * the "am" command to report errors with more information.
14574     *
14575     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14576     * @param cn The component name of the instrumentation.
14577     * @param report The error report.
14578     */
14579    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14580            ComponentName cn, String report) {
14581        Slog.w(TAG, report);
14582        try {
14583            if (watcher != null) {
14584                Bundle results = new Bundle();
14585                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14586                results.putString("Error", report);
14587                watcher.instrumentationStatus(cn, -1, results);
14588            }
14589        } catch (RemoteException e) {
14590            Slog.w(TAG, e);
14591        }
14592    }
14593
14594    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14595        if (app.instrumentationWatcher != null) {
14596            try {
14597                // NOTE:  IInstrumentationWatcher *must* be oneway here
14598                app.instrumentationWatcher.instrumentationFinished(
14599                    app.instrumentationClass,
14600                    resultCode,
14601                    results);
14602            } catch (RemoteException e) {
14603            }
14604        }
14605        if (app.instrumentationUiAutomationConnection != null) {
14606            try {
14607                app.instrumentationUiAutomationConnection.shutdown();
14608            } catch (RemoteException re) {
14609                /* ignore */
14610            }
14611            // Only a UiAutomation can set this flag and now that
14612            // it is finished we make sure it is reset to its default.
14613            mUserIsMonkey = false;
14614        }
14615        app.instrumentationWatcher = null;
14616        app.instrumentationUiAutomationConnection = null;
14617        app.instrumentationClass = null;
14618        app.instrumentationInfo = null;
14619        app.instrumentationProfileFile = null;
14620        app.instrumentationArguments = null;
14621
14622        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14623                "finished inst");
14624    }
14625
14626    public void finishInstrumentation(IApplicationThread target,
14627            int resultCode, Bundle results) {
14628        int userId = UserHandle.getCallingUserId();
14629        // Refuse possible leaked file descriptors
14630        if (results != null && results.hasFileDescriptors()) {
14631            throw new IllegalArgumentException("File descriptors passed in Intent");
14632        }
14633
14634        synchronized(this) {
14635            ProcessRecord app = getRecordForAppLocked(target);
14636            if (app == null) {
14637                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14638                return;
14639            }
14640            final long origId = Binder.clearCallingIdentity();
14641            finishInstrumentationLocked(app, resultCode, results);
14642            Binder.restoreCallingIdentity(origId);
14643        }
14644    }
14645
14646    // =========================================================
14647    // CONFIGURATION
14648    // =========================================================
14649
14650    public ConfigurationInfo getDeviceConfigurationInfo() {
14651        ConfigurationInfo config = new ConfigurationInfo();
14652        synchronized (this) {
14653            config.reqTouchScreen = mConfiguration.touchscreen;
14654            config.reqKeyboardType = mConfiguration.keyboard;
14655            config.reqNavigation = mConfiguration.navigation;
14656            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14657                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14658                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14659            }
14660            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14661                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14662                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14663            }
14664            config.reqGlEsVersion = GL_ES_VERSION;
14665        }
14666        return config;
14667    }
14668
14669    ActivityStack getFocusedStack() {
14670        return mStackSupervisor.getFocusedStack();
14671    }
14672
14673    public Configuration getConfiguration() {
14674        Configuration ci;
14675        synchronized(this) {
14676            ci = new Configuration(mConfiguration);
14677        }
14678        return ci;
14679    }
14680
14681    public void updatePersistentConfiguration(Configuration values) {
14682        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14683                "updateConfiguration()");
14684        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14685                "updateConfiguration()");
14686        if (values == null) {
14687            throw new NullPointerException("Configuration must not be null");
14688        }
14689
14690        synchronized(this) {
14691            final long origId = Binder.clearCallingIdentity();
14692            updateConfigurationLocked(values, null, true, false);
14693            Binder.restoreCallingIdentity(origId);
14694        }
14695    }
14696
14697    public void updateConfiguration(Configuration values) {
14698        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14699                "updateConfiguration()");
14700
14701        synchronized(this) {
14702            if (values == null && mWindowManager != null) {
14703                // sentinel: fetch the current configuration from the window manager
14704                values = mWindowManager.computeNewConfiguration();
14705            }
14706
14707            if (mWindowManager != null) {
14708                mProcessList.applyDisplaySize(mWindowManager);
14709            }
14710
14711            final long origId = Binder.clearCallingIdentity();
14712            if (values != null) {
14713                Settings.System.clearConfiguration(values);
14714            }
14715            updateConfigurationLocked(values, null, false, false);
14716            Binder.restoreCallingIdentity(origId);
14717        }
14718    }
14719
14720    /**
14721     * Do either or both things: (1) change the current configuration, and (2)
14722     * make sure the given activity is running with the (now) current
14723     * configuration.  Returns true if the activity has been left running, or
14724     * false if <var>starting</var> is being destroyed to match the new
14725     * configuration.
14726     * @param persistent TODO
14727     */
14728    boolean updateConfigurationLocked(Configuration values,
14729            ActivityRecord starting, boolean persistent, boolean initLocale) {
14730        int changes = 0;
14731
14732        if (values != null) {
14733            Configuration newConfig = new Configuration(mConfiguration);
14734            changes = newConfig.updateFrom(values);
14735            if (changes != 0) {
14736                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14737                    Slog.i(TAG, "Updating configuration to: " + values);
14738                }
14739
14740                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14741
14742                if (values.locale != null && !initLocale) {
14743                    saveLocaleLocked(values.locale,
14744                                     !values.locale.equals(mConfiguration.locale),
14745                                     values.userSetLocale);
14746                }
14747
14748                mConfigurationSeq++;
14749                if (mConfigurationSeq <= 0) {
14750                    mConfigurationSeq = 1;
14751                }
14752                newConfig.seq = mConfigurationSeq;
14753                mConfiguration = newConfig;
14754                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14755                mUsageStatsService.noteStartConfig(newConfig);
14756
14757                final Configuration configCopy = new Configuration(mConfiguration);
14758
14759                // TODO: If our config changes, should we auto dismiss any currently
14760                // showing dialogs?
14761                mShowDialogs = shouldShowDialogs(newConfig);
14762
14763                AttributeCache ac = AttributeCache.instance();
14764                if (ac != null) {
14765                    ac.updateConfiguration(configCopy);
14766                }
14767
14768                // Make sure all resources in our process are updated
14769                // right now, so that anyone who is going to retrieve
14770                // resource values after we return will be sure to get
14771                // the new ones.  This is especially important during
14772                // boot, where the first config change needs to guarantee
14773                // all resources have that config before following boot
14774                // code is executed.
14775                mSystemThread.applyConfigurationToResources(configCopy);
14776
14777                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14778                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14779                    msg.obj = new Configuration(configCopy);
14780                    mHandler.sendMessage(msg);
14781                }
14782
14783                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14784                    ProcessRecord app = mLruProcesses.get(i);
14785                    try {
14786                        if (app.thread != null) {
14787                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14788                                    + app.processName + " new config " + mConfiguration);
14789                            app.thread.scheduleConfigurationChanged(configCopy);
14790                        }
14791                    } catch (Exception e) {
14792                    }
14793                }
14794                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14795                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14796                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14797                        | Intent.FLAG_RECEIVER_FOREGROUND);
14798                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14799                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14800                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14801                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14802                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14803                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14804                    broadcastIntentLocked(null, null, intent,
14805                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14806                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14807                }
14808            }
14809        }
14810
14811        boolean kept = true;
14812        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14813        // mainStack is null during startup.
14814        if (mainStack != null) {
14815            if (changes != 0 && starting == null) {
14816                // If the configuration changed, and the caller is not already
14817                // in the process of starting an activity, then find the top
14818                // activity to check if its configuration needs to change.
14819                starting = mainStack.topRunningActivityLocked(null);
14820            }
14821
14822            if (starting != null) {
14823                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14824                // And we need to make sure at this point that all other activities
14825                // are made visible with the correct configuration.
14826                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14827            }
14828        }
14829
14830        if (values != null && mWindowManager != null) {
14831            mWindowManager.setNewConfiguration(mConfiguration);
14832        }
14833
14834        return kept;
14835    }
14836
14837    /**
14838     * Decide based on the configuration whether we should shouw the ANR,
14839     * crash, etc dialogs.  The idea is that if there is no affordnace to
14840     * press the on-screen buttons, we shouldn't show the dialog.
14841     *
14842     * A thought: SystemUI might also want to get told about this, the Power
14843     * dialog / global actions also might want different behaviors.
14844     */
14845    private static final boolean shouldShowDialogs(Configuration config) {
14846        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14847                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14848    }
14849
14850    /**
14851     * Save the locale.  You must be inside a synchronized (this) block.
14852     */
14853    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14854        if(isDiff) {
14855            SystemProperties.set("user.language", l.getLanguage());
14856            SystemProperties.set("user.region", l.getCountry());
14857        }
14858
14859        if(isPersist) {
14860            SystemProperties.set("persist.sys.language", l.getLanguage());
14861            SystemProperties.set("persist.sys.country", l.getCountry());
14862            SystemProperties.set("persist.sys.localevar", l.getVariant());
14863        }
14864    }
14865
14866    @Override
14867    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14868        ActivityRecord srec = ActivityRecord.forToken(token);
14869        return srec != null && srec.task.affinity != null &&
14870                srec.task.affinity.equals(destAffinity);
14871    }
14872
14873    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14874            Intent resultData) {
14875
14876        synchronized (this) {
14877            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14878            if (stack != null) {
14879                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14880            }
14881            return false;
14882        }
14883    }
14884
14885    public int getLaunchedFromUid(IBinder activityToken) {
14886        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14887        if (srec == null) {
14888            return -1;
14889        }
14890        return srec.launchedFromUid;
14891    }
14892
14893    public String getLaunchedFromPackage(IBinder activityToken) {
14894        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14895        if (srec == null) {
14896            return null;
14897        }
14898        return srec.launchedFromPackage;
14899    }
14900
14901    // =========================================================
14902    // LIFETIME MANAGEMENT
14903    // =========================================================
14904
14905    // Returns which broadcast queue the app is the current [or imminent] receiver
14906    // on, or 'null' if the app is not an active broadcast recipient.
14907    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14908        BroadcastRecord r = app.curReceiver;
14909        if (r != null) {
14910            return r.queue;
14911        }
14912
14913        // It's not the current receiver, but it might be starting up to become one
14914        synchronized (this) {
14915            for (BroadcastQueue queue : mBroadcastQueues) {
14916                r = queue.mPendingBroadcast;
14917                if (r != null && r.curApp == app) {
14918                    // found it; report which queue it's in
14919                    return queue;
14920                }
14921            }
14922        }
14923
14924        return null;
14925    }
14926
14927    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14928            boolean doingAll, long now) {
14929        if (mAdjSeq == app.adjSeq) {
14930            // This adjustment has already been computed.
14931            return app.curRawAdj;
14932        }
14933
14934        if (app.thread == null) {
14935            app.adjSeq = mAdjSeq;
14936            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14937            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14938            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14939        }
14940
14941        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14942        app.adjSource = null;
14943        app.adjTarget = null;
14944        app.empty = false;
14945        app.cached = false;
14946
14947        final int activitiesSize = app.activities.size();
14948
14949        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14950            // The max adjustment doesn't allow this app to be anything
14951            // below foreground, so it is not worth doing work for it.
14952            app.adjType = "fixed";
14953            app.adjSeq = mAdjSeq;
14954            app.curRawAdj = app.maxAdj;
14955            app.foregroundActivities = false;
14956            app.keeping = true;
14957            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14958            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14959            // System processes can do UI, and when they do we want to have
14960            // them trim their memory after the user leaves the UI.  To
14961            // facilitate this, here we need to determine whether or not it
14962            // is currently showing UI.
14963            app.systemNoUi = true;
14964            if (app == TOP_APP) {
14965                app.systemNoUi = false;
14966            } else if (activitiesSize > 0) {
14967                for (int j = 0; j < activitiesSize; j++) {
14968                    final ActivityRecord r = app.activities.get(j);
14969                    if (r.visible) {
14970                        app.systemNoUi = false;
14971                    }
14972                }
14973            }
14974            if (!app.systemNoUi) {
14975                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14976            }
14977            return (app.curAdj=app.maxAdj);
14978        }
14979
14980        app.keeping = false;
14981        app.systemNoUi = false;
14982
14983        // Determine the importance of the process, starting with most
14984        // important to least, and assign an appropriate OOM adjustment.
14985        int adj;
14986        int schedGroup;
14987        int procState;
14988        boolean foregroundActivities = false;
14989        boolean interesting = false;
14990        BroadcastQueue queue;
14991        if (app == TOP_APP) {
14992            // The last app on the list is the foreground app.
14993            adj = ProcessList.FOREGROUND_APP_ADJ;
14994            schedGroup = Process.THREAD_GROUP_DEFAULT;
14995            app.adjType = "top-activity";
14996            foregroundActivities = true;
14997            interesting = true;
14998            procState = ActivityManager.PROCESS_STATE_TOP;
14999        } else if (app.instrumentationClass != null) {
15000            // Don't want to kill running instrumentation.
15001            adj = ProcessList.FOREGROUND_APP_ADJ;
15002            schedGroup = Process.THREAD_GROUP_DEFAULT;
15003            app.adjType = "instrumentation";
15004            interesting = true;
15005            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15006        } else if ((queue = isReceivingBroadcast(app)) != null) {
15007            // An app that is currently receiving a broadcast also
15008            // counts as being in the foreground for OOM killer purposes.
15009            // It's placed in a sched group based on the nature of the
15010            // broadcast as reflected by which queue it's active in.
15011            adj = ProcessList.FOREGROUND_APP_ADJ;
15012            schedGroup = (queue == mFgBroadcastQueue)
15013                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15014            app.adjType = "broadcast";
15015            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15016        } else if (app.executingServices.size() > 0) {
15017            // An app that is currently executing a service callback also
15018            // counts as being in the foreground.
15019            adj = ProcessList.FOREGROUND_APP_ADJ;
15020            schedGroup = app.execServicesFg ?
15021                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15022            app.adjType = "exec-service";
15023            procState = ActivityManager.PROCESS_STATE_SERVICE;
15024            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15025        } else {
15026            // As far as we know the process is empty.  We may change our mind later.
15027            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15028            // At this point we don't actually know the adjustment.  Use the cached adj
15029            // value that the caller wants us to.
15030            adj = cachedAdj;
15031            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15032            app.cached = true;
15033            app.empty = true;
15034            app.adjType = "cch-empty";
15035        }
15036
15037        // Examine all activities if not already foreground.
15038        if (!foregroundActivities && activitiesSize > 0) {
15039            for (int j = 0; j < activitiesSize; j++) {
15040                final ActivityRecord r = app.activities.get(j);
15041                if (r.app != app) {
15042                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15043                            + app + "?!?");
15044                    continue;
15045                }
15046                if (r.visible) {
15047                    // App has a visible activity; only upgrade adjustment.
15048                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15049                        adj = ProcessList.VISIBLE_APP_ADJ;
15050                        app.adjType = "visible";
15051                    }
15052                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15053                        procState = ActivityManager.PROCESS_STATE_TOP;
15054                    }
15055                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15056                    app.cached = false;
15057                    app.empty = false;
15058                    foregroundActivities = true;
15059                    break;
15060                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15061                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15062                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15063                        app.adjType = "pausing";
15064                    }
15065                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15066                        procState = ActivityManager.PROCESS_STATE_TOP;
15067                    }
15068                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15069                    app.cached = false;
15070                    app.empty = false;
15071                    foregroundActivities = true;
15072                } else if (r.state == ActivityState.STOPPING) {
15073                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15074                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15075                        app.adjType = "stopping";
15076                    }
15077                    // For the process state, we will at this point consider the
15078                    // process to be cached.  It will be cached either as an activity
15079                    // or empty depending on whether the activity is finishing.  We do
15080                    // this so that we can treat the process as cached for purposes of
15081                    // memory trimming (determing current memory level, trim command to
15082                    // send to process) since there can be an arbitrary number of stopping
15083                    // processes and they should soon all go into the cached state.
15084                    if (!r.finishing) {
15085                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15086                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15087                        }
15088                    }
15089                    app.cached = false;
15090                    app.empty = false;
15091                    foregroundActivities = true;
15092                } else {
15093                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15094                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15095                        app.adjType = "cch-act";
15096                    }
15097                }
15098            }
15099        }
15100
15101        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15102            if (app.foregroundServices) {
15103                // The user is aware of this app, so make it visible.
15104                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15105                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15106                app.cached = false;
15107                app.adjType = "fg-service";
15108                schedGroup = Process.THREAD_GROUP_DEFAULT;
15109            } else if (app.forcingToForeground != null) {
15110                // The user is aware of this app, so make it visible.
15111                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15112                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15113                app.cached = false;
15114                app.adjType = "force-fg";
15115                app.adjSource = app.forcingToForeground;
15116                schedGroup = Process.THREAD_GROUP_DEFAULT;
15117            }
15118        }
15119
15120        if (app.foregroundServices) {
15121            interesting = true;
15122        }
15123
15124        if (app == mHeavyWeightProcess) {
15125            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15126                // We don't want to kill the current heavy-weight process.
15127                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15128                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15129                app.cached = false;
15130                app.adjType = "heavy";
15131            }
15132            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15133                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15134            }
15135        }
15136
15137        if (app == mHomeProcess) {
15138            if (adj > ProcessList.HOME_APP_ADJ) {
15139                // This process is hosting what we currently consider to be the
15140                // home app, so we don't want to let it go into the background.
15141                adj = ProcessList.HOME_APP_ADJ;
15142                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15143                app.cached = false;
15144                app.adjType = "home";
15145            }
15146            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15147                procState = ActivityManager.PROCESS_STATE_HOME;
15148            }
15149        }
15150
15151        if (app == mPreviousProcess && app.activities.size() > 0) {
15152            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15153                // This was the previous process that showed UI to the user.
15154                // We want to try to keep it around more aggressively, to give
15155                // a good experience around switching between two apps.
15156                adj = ProcessList.PREVIOUS_APP_ADJ;
15157                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15158                app.cached = false;
15159                app.adjType = "previous";
15160            }
15161            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15162                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15163            }
15164        }
15165
15166        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15167                + " reason=" + app.adjType);
15168
15169        // By default, we use the computed adjustment.  It may be changed if
15170        // there are applications dependent on our services or providers, but
15171        // this gives us a baseline and makes sure we don't get into an
15172        // infinite recursion.
15173        app.adjSeq = mAdjSeq;
15174        app.curRawAdj = adj;
15175        app.hasStartedServices = false;
15176
15177        if (mBackupTarget != null && app == mBackupTarget.app) {
15178            // If possible we want to avoid killing apps while they're being backed up
15179            if (adj > ProcessList.BACKUP_APP_ADJ) {
15180                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15181                adj = ProcessList.BACKUP_APP_ADJ;
15182                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15183                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15184                }
15185                app.adjType = "backup";
15186                app.cached = false;
15187            }
15188            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15189                procState = ActivityManager.PROCESS_STATE_BACKUP;
15190            }
15191        }
15192
15193        boolean mayBeTop = false;
15194
15195        for (int is = app.services.size()-1;
15196                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15197                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15198                        || procState > ActivityManager.PROCESS_STATE_TOP);
15199                is--) {
15200            ServiceRecord s = app.services.valueAt(is);
15201            if (s.startRequested) {
15202                app.hasStartedServices = true;
15203                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15204                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15205                }
15206                if (app.hasShownUi && app != mHomeProcess) {
15207                    // If this process has shown some UI, let it immediately
15208                    // go to the LRU list because it may be pretty heavy with
15209                    // UI stuff.  We'll tag it with a label just to help
15210                    // debug and understand what is going on.
15211                    if (adj > ProcessList.SERVICE_ADJ) {
15212                        app.adjType = "cch-started-ui-services";
15213                    }
15214                } else {
15215                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15216                        // This service has seen some activity within
15217                        // recent memory, so we will keep its process ahead
15218                        // of the background processes.
15219                        if (adj > ProcessList.SERVICE_ADJ) {
15220                            adj = ProcessList.SERVICE_ADJ;
15221                            app.adjType = "started-services";
15222                            app.cached = false;
15223                        }
15224                    }
15225                    // If we have let the service slide into the background
15226                    // state, still have some text describing what it is doing
15227                    // even though the service no longer has an impact.
15228                    if (adj > ProcessList.SERVICE_ADJ) {
15229                        app.adjType = "cch-started-services";
15230                    }
15231                }
15232                // Don't kill this process because it is doing work; it
15233                // has said it is doing work.
15234                app.keeping = true;
15235            }
15236            for (int conni = s.connections.size()-1;
15237                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15238                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15239                            || procState > ActivityManager.PROCESS_STATE_TOP);
15240                    conni--) {
15241                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15242                for (int i = 0;
15243                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15244                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15245                                || procState > ActivityManager.PROCESS_STATE_TOP);
15246                        i++) {
15247                    // XXX should compute this based on the max of
15248                    // all connected clients.
15249                    ConnectionRecord cr = clist.get(i);
15250                    if (cr.binding.client == app) {
15251                        // Binding to ourself is not interesting.
15252                        continue;
15253                    }
15254                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15255                        ProcessRecord client = cr.binding.client;
15256                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15257                                TOP_APP, doingAll, now);
15258                        int clientProcState = client.curProcState;
15259                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15260                            // If the other app is cached for any reason, for purposes here
15261                            // we are going to consider it empty.  The specific cached state
15262                            // doesn't propagate except under certain conditions.
15263                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15264                        }
15265                        String adjType = null;
15266                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15267                            // Not doing bind OOM management, so treat
15268                            // this guy more like a started service.
15269                            if (app.hasShownUi && app != mHomeProcess) {
15270                                // If this process has shown some UI, let it immediately
15271                                // go to the LRU list because it may be pretty heavy with
15272                                // UI stuff.  We'll tag it with a label just to help
15273                                // debug and understand what is going on.
15274                                if (adj > clientAdj) {
15275                                    adjType = "cch-bound-ui-services";
15276                                }
15277                                app.cached = false;
15278                                clientAdj = adj;
15279                                clientProcState = procState;
15280                            } else {
15281                                if (now >= (s.lastActivity
15282                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15283                                    // This service has not seen activity within
15284                                    // recent memory, so allow it to drop to the
15285                                    // LRU list if there is no other reason to keep
15286                                    // it around.  We'll also tag it with a label just
15287                                    // to help debug and undertand what is going on.
15288                                    if (adj > clientAdj) {
15289                                        adjType = "cch-bound-services";
15290                                    }
15291                                    clientAdj = adj;
15292                                }
15293                            }
15294                        }
15295                        if (adj > clientAdj) {
15296                            // If this process has recently shown UI, and
15297                            // the process that is binding to it is less
15298                            // important than being visible, then we don't
15299                            // care about the binding as much as we care
15300                            // about letting this process get into the LRU
15301                            // list to be killed and restarted if needed for
15302                            // memory.
15303                            if (app.hasShownUi && app != mHomeProcess
15304                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15305                                adjType = "cch-bound-ui-services";
15306                            } else {
15307                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15308                                        |Context.BIND_IMPORTANT)) != 0) {
15309                                    adj = clientAdj;
15310                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15311                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15312                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15313                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15314                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15315                                    adj = clientAdj;
15316                                } else {
15317                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15318                                        adj = ProcessList.VISIBLE_APP_ADJ;
15319                                    }
15320                                }
15321                                if (!client.cached) {
15322                                    app.cached = false;
15323                                }
15324                                if (client.keeping) {
15325                                    app.keeping = true;
15326                                }
15327                                adjType = "service";
15328                            }
15329                        }
15330                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15331                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15332                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15333                            }
15334                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15335                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15336                                    // Special handling of clients who are in the top state.
15337                                    // We *may* want to consider this process to be in the
15338                                    // top state as well, but only if there is not another
15339                                    // reason for it to be running.  Being on the top is a
15340                                    // special state, meaning you are specifically running
15341                                    // for the current top app.  If the process is already
15342                                    // running in the background for some other reason, it
15343                                    // is more important to continue considering it to be
15344                                    // in the background state.
15345                                    mayBeTop = true;
15346                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15347                                } else {
15348                                    // Special handling for above-top states (persistent
15349                                    // processes).  These should not bring the current process
15350                                    // into the top state, since they are not on top.  Instead
15351                                    // give them the best state after that.
15352                                    clientProcState =
15353                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15354                                }
15355                            }
15356                        } else {
15357                            if (clientProcState <
15358                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15359                                clientProcState =
15360                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15361                            }
15362                        }
15363                        if (procState > clientProcState) {
15364                            procState = clientProcState;
15365                        }
15366                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15367                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15368                            app.pendingUiClean = true;
15369                        }
15370                        if (adjType != null) {
15371                            app.adjType = adjType;
15372                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15373                                    .REASON_SERVICE_IN_USE;
15374                            app.adjSource = cr.binding.client;
15375                            app.adjSourceOom = clientAdj;
15376                            app.adjTarget = s.name;
15377                        }
15378                    }
15379                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15380                        app.treatLikeActivity = true;
15381                    }
15382                    final ActivityRecord a = cr.activity;
15383                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15384                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15385                                (a.visible || a.state == ActivityState.RESUMED
15386                                 || a.state == ActivityState.PAUSING)) {
15387                            adj = ProcessList.FOREGROUND_APP_ADJ;
15388                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15389                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15390                            }
15391                            app.cached = false;
15392                            app.adjType = "service";
15393                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15394                                    .REASON_SERVICE_IN_USE;
15395                            app.adjSource = a;
15396                            app.adjSourceOom = adj;
15397                            app.adjTarget = s.name;
15398                        }
15399                    }
15400                }
15401            }
15402        }
15403
15404        for (int provi = app.pubProviders.size()-1;
15405                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15406                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15407                        || procState > ActivityManager.PROCESS_STATE_TOP);
15408                provi--) {
15409            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15410            for (int i = cpr.connections.size()-1;
15411                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15412                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15413                            || procState > ActivityManager.PROCESS_STATE_TOP);
15414                    i--) {
15415                ContentProviderConnection conn = cpr.connections.get(i);
15416                ProcessRecord client = conn.client;
15417                if (client == app) {
15418                    // Being our own client is not interesting.
15419                    continue;
15420                }
15421                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15422                int clientProcState = client.curProcState;
15423                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15424                    // If the other app is cached for any reason, for purposes here
15425                    // we are going to consider it empty.
15426                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15427                }
15428                if (adj > clientAdj) {
15429                    if (app.hasShownUi && app != mHomeProcess
15430                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15431                        app.adjType = "cch-ui-provider";
15432                    } else {
15433                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15434                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15435                        app.adjType = "provider";
15436                    }
15437                    app.cached &= client.cached;
15438                    app.keeping |= client.keeping;
15439                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15440                            .REASON_PROVIDER_IN_USE;
15441                    app.adjSource = client;
15442                    app.adjSourceOom = clientAdj;
15443                    app.adjTarget = cpr.name;
15444                }
15445                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15446                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15447                        // Special handling of clients who are in the top state.
15448                        // We *may* want to consider this process to be in the
15449                        // top state as well, but only if there is not another
15450                        // reason for it to be running.  Being on the top is a
15451                        // special state, meaning you are specifically running
15452                        // for the current top app.  If the process is already
15453                        // running in the background for some other reason, it
15454                        // is more important to continue considering it to be
15455                        // in the background state.
15456                        mayBeTop = true;
15457                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15458                    } else {
15459                        // Special handling for above-top states (persistent
15460                        // processes).  These should not bring the current process
15461                        // into the top state, since they are not on top.  Instead
15462                        // give them the best state after that.
15463                        clientProcState =
15464                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15465                    }
15466                }
15467                if (procState > clientProcState) {
15468                    procState = clientProcState;
15469                }
15470                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15471                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15472                }
15473            }
15474            // If the provider has external (non-framework) process
15475            // dependencies, ensure that its adjustment is at least
15476            // FOREGROUND_APP_ADJ.
15477            if (cpr.hasExternalProcessHandles()) {
15478                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15479                    adj = ProcessList.FOREGROUND_APP_ADJ;
15480                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15481                    app.cached = false;
15482                    app.keeping = true;
15483                    app.adjType = "provider";
15484                    app.adjTarget = cpr.name;
15485                }
15486                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15487                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15488                }
15489            }
15490        }
15491
15492        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15493            // A client of one of our services or providers is in the top state.  We
15494            // *may* want to be in the top state, but not if we are already running in
15495            // the background for some other reason.  For the decision here, we are going
15496            // to pick out a few specific states that we want to remain in when a client
15497            // is top (states that tend to be longer-term) and otherwise allow it to go
15498            // to the top state.
15499            switch (procState) {
15500                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15501                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15502                case ActivityManager.PROCESS_STATE_SERVICE:
15503                    // These all are longer-term states, so pull them up to the top
15504                    // of the background states, but not all the way to the top state.
15505                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15506                    break;
15507                default:
15508                    // Otherwise, top is a better choice, so take it.
15509                    procState = ActivityManager.PROCESS_STATE_TOP;
15510                    break;
15511            }
15512        }
15513
15514        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15515            if (app.hasClientActivities) {
15516                // This is a cached process, but with client activities.  Mark it so.
15517                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15518                app.adjType = "cch-client-act";
15519            } else if (app.treatLikeActivity) {
15520                // This is a cached process, but somebody wants us to treat it like it has
15521                // an activity, okay!
15522                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15523                app.adjType = "cch-as-act";
15524            }
15525        }
15526
15527        if (adj == ProcessList.SERVICE_ADJ) {
15528            if (doingAll) {
15529                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15530                mNewNumServiceProcs++;
15531                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15532                if (!app.serviceb) {
15533                    // This service isn't far enough down on the LRU list to
15534                    // normally be a B service, but if we are low on RAM and it
15535                    // is large we want to force it down since we would prefer to
15536                    // keep launcher over it.
15537                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15538                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15539                        app.serviceHighRam = true;
15540                        app.serviceb = true;
15541                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15542                    } else {
15543                        mNewNumAServiceProcs++;
15544                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15545                    }
15546                } else {
15547                    app.serviceHighRam = false;
15548                }
15549            }
15550            if (app.serviceb) {
15551                adj = ProcessList.SERVICE_B_ADJ;
15552            }
15553        }
15554
15555        app.curRawAdj = adj;
15556
15557        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15558        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15559        if (adj > app.maxAdj) {
15560            adj = app.maxAdj;
15561            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15562                schedGroup = Process.THREAD_GROUP_DEFAULT;
15563            }
15564        }
15565        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15566            app.keeping = true;
15567        }
15568
15569        // Do final modification to adj.  Everything we do between here and applying
15570        // the final setAdj must be done in this function, because we will also use
15571        // it when computing the final cached adj later.  Note that we don't need to
15572        // worry about this for max adj above, since max adj will always be used to
15573        // keep it out of the cached vaues.
15574        app.curAdj = app.modifyRawOomAdj(adj);
15575        app.curSchedGroup = schedGroup;
15576        app.curProcState = procState;
15577        app.foregroundActivities = foregroundActivities;
15578
15579        return app.curRawAdj;
15580    }
15581
15582    /**
15583     * Schedule PSS collection of a process.
15584     */
15585    void requestPssLocked(ProcessRecord proc, int procState) {
15586        if (mPendingPssProcesses.contains(proc)) {
15587            return;
15588        }
15589        if (mPendingPssProcesses.size() == 0) {
15590            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15591        }
15592        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15593        proc.pssProcState = procState;
15594        mPendingPssProcesses.add(proc);
15595    }
15596
15597    /**
15598     * Schedule PSS collection of all processes.
15599     */
15600    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15601        if (!always) {
15602            if (now < (mLastFullPssTime +
15603                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15604                return;
15605            }
15606        }
15607        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15608        mLastFullPssTime = now;
15609        mFullPssPending = true;
15610        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15611        mPendingPssProcesses.clear();
15612        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15613            ProcessRecord app = mLruProcesses.get(i);
15614            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15615                app.pssProcState = app.setProcState;
15616                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15617                        isSleeping(), now);
15618                mPendingPssProcesses.add(app);
15619            }
15620        }
15621        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15622    }
15623
15624    /**
15625     * Ask a given process to GC right now.
15626     */
15627    final void performAppGcLocked(ProcessRecord app) {
15628        try {
15629            app.lastRequestedGc = SystemClock.uptimeMillis();
15630            if (app.thread != null) {
15631                if (app.reportLowMemory) {
15632                    app.reportLowMemory = false;
15633                    app.thread.scheduleLowMemory();
15634                } else {
15635                    app.thread.processInBackground();
15636                }
15637            }
15638        } catch (Exception e) {
15639            // whatever.
15640        }
15641    }
15642
15643    /**
15644     * Returns true if things are idle enough to perform GCs.
15645     */
15646    private final boolean canGcNowLocked() {
15647        boolean processingBroadcasts = false;
15648        for (BroadcastQueue q : mBroadcastQueues) {
15649            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15650                processingBroadcasts = true;
15651            }
15652        }
15653        return !processingBroadcasts
15654                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15655    }
15656
15657    /**
15658     * Perform GCs on all processes that are waiting for it, but only
15659     * if things are idle.
15660     */
15661    final void performAppGcsLocked() {
15662        final int N = mProcessesToGc.size();
15663        if (N <= 0) {
15664            return;
15665        }
15666        if (canGcNowLocked()) {
15667            while (mProcessesToGc.size() > 0) {
15668                ProcessRecord proc = mProcessesToGc.remove(0);
15669                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15670                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15671                            <= SystemClock.uptimeMillis()) {
15672                        // To avoid spamming the system, we will GC processes one
15673                        // at a time, waiting a few seconds between each.
15674                        performAppGcLocked(proc);
15675                        scheduleAppGcsLocked();
15676                        return;
15677                    } else {
15678                        // It hasn't been long enough since we last GCed this
15679                        // process...  put it in the list to wait for its time.
15680                        addProcessToGcListLocked(proc);
15681                        break;
15682                    }
15683                }
15684            }
15685
15686            scheduleAppGcsLocked();
15687        }
15688    }
15689
15690    /**
15691     * If all looks good, perform GCs on all processes waiting for them.
15692     */
15693    final void performAppGcsIfAppropriateLocked() {
15694        if (canGcNowLocked()) {
15695            performAppGcsLocked();
15696            return;
15697        }
15698        // Still not idle, wait some more.
15699        scheduleAppGcsLocked();
15700    }
15701
15702    /**
15703     * Schedule the execution of all pending app GCs.
15704     */
15705    final void scheduleAppGcsLocked() {
15706        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15707
15708        if (mProcessesToGc.size() > 0) {
15709            // Schedule a GC for the time to the next process.
15710            ProcessRecord proc = mProcessesToGc.get(0);
15711            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15712
15713            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15714            long now = SystemClock.uptimeMillis();
15715            if (when < (now+GC_TIMEOUT)) {
15716                when = now + GC_TIMEOUT;
15717            }
15718            mHandler.sendMessageAtTime(msg, when);
15719        }
15720    }
15721
15722    /**
15723     * Add a process to the array of processes waiting to be GCed.  Keeps the
15724     * list in sorted order by the last GC time.  The process can't already be
15725     * on the list.
15726     */
15727    final void addProcessToGcListLocked(ProcessRecord proc) {
15728        boolean added = false;
15729        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15730            if (mProcessesToGc.get(i).lastRequestedGc <
15731                    proc.lastRequestedGc) {
15732                added = true;
15733                mProcessesToGc.add(i+1, proc);
15734                break;
15735            }
15736        }
15737        if (!added) {
15738            mProcessesToGc.add(0, proc);
15739        }
15740    }
15741
15742    /**
15743     * Set up to ask a process to GC itself.  This will either do it
15744     * immediately, or put it on the list of processes to gc the next
15745     * time things are idle.
15746     */
15747    final void scheduleAppGcLocked(ProcessRecord app) {
15748        long now = SystemClock.uptimeMillis();
15749        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15750            return;
15751        }
15752        if (!mProcessesToGc.contains(app)) {
15753            addProcessToGcListLocked(app);
15754            scheduleAppGcsLocked();
15755        }
15756    }
15757
15758    final void checkExcessivePowerUsageLocked(boolean doKills) {
15759        updateCpuStatsNow();
15760
15761        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15762        boolean doWakeKills = doKills;
15763        boolean doCpuKills = doKills;
15764        if (mLastPowerCheckRealtime == 0) {
15765            doWakeKills = false;
15766        }
15767        if (mLastPowerCheckUptime == 0) {
15768            doCpuKills = false;
15769        }
15770        if (stats.isScreenOn()) {
15771            doWakeKills = false;
15772        }
15773        final long curRealtime = SystemClock.elapsedRealtime();
15774        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15775        final long curUptime = SystemClock.uptimeMillis();
15776        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15777        mLastPowerCheckRealtime = curRealtime;
15778        mLastPowerCheckUptime = curUptime;
15779        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15780            doWakeKills = false;
15781        }
15782        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15783            doCpuKills = false;
15784        }
15785        int i = mLruProcesses.size();
15786        while (i > 0) {
15787            i--;
15788            ProcessRecord app = mLruProcesses.get(i);
15789            if (!app.keeping) {
15790                long wtime;
15791                synchronized (stats) {
15792                    wtime = stats.getProcessWakeTime(app.info.uid,
15793                            app.pid, curRealtime);
15794                }
15795                long wtimeUsed = wtime - app.lastWakeTime;
15796                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15797                if (DEBUG_POWER) {
15798                    StringBuilder sb = new StringBuilder(128);
15799                    sb.append("Wake for ");
15800                    app.toShortString(sb);
15801                    sb.append(": over ");
15802                    TimeUtils.formatDuration(realtimeSince, sb);
15803                    sb.append(" used ");
15804                    TimeUtils.formatDuration(wtimeUsed, sb);
15805                    sb.append(" (");
15806                    sb.append((wtimeUsed*100)/realtimeSince);
15807                    sb.append("%)");
15808                    Slog.i(TAG, sb.toString());
15809                    sb.setLength(0);
15810                    sb.append("CPU for ");
15811                    app.toShortString(sb);
15812                    sb.append(": over ");
15813                    TimeUtils.formatDuration(uptimeSince, sb);
15814                    sb.append(" used ");
15815                    TimeUtils.formatDuration(cputimeUsed, sb);
15816                    sb.append(" (");
15817                    sb.append((cputimeUsed*100)/uptimeSince);
15818                    sb.append("%)");
15819                    Slog.i(TAG, sb.toString());
15820                }
15821                // If a process has held a wake lock for more
15822                // than 50% of the time during this period,
15823                // that sounds bad.  Kill!
15824                if (doWakeKills && realtimeSince > 0
15825                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15826                    synchronized (stats) {
15827                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15828                                realtimeSince, wtimeUsed);
15829                    }
15830                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15831                            + " during " + realtimeSince);
15832                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15833                } else if (doCpuKills && uptimeSince > 0
15834                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15835                    synchronized (stats) {
15836                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15837                                uptimeSince, cputimeUsed);
15838                    }
15839                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15840                            + " during " + uptimeSince);
15841                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15842                } else {
15843                    app.lastWakeTime = wtime;
15844                    app.lastCpuTime = app.curCpuTime;
15845                }
15846            }
15847        }
15848    }
15849
15850    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15851            ProcessRecord TOP_APP, boolean doingAll, long now) {
15852        boolean success = true;
15853
15854        if (app.curRawAdj != app.setRawAdj) {
15855            if (wasKeeping && !app.keeping) {
15856                // This app is no longer something we want to keep.  Note
15857                // its current wake lock time to later know to kill it if
15858                // it is not behaving well.
15859                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15860                synchronized (stats) {
15861                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15862                            app.pid, SystemClock.elapsedRealtime());
15863                }
15864                app.lastCpuTime = app.curCpuTime;
15865            }
15866
15867            app.setRawAdj = app.curRawAdj;
15868        }
15869
15870        int changes = 0;
15871
15872        if (app.curAdj != app.setAdj) {
15873            ProcessList.setOomAdj(app.pid, app.curAdj);
15874            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15875                TAG, "Set " + app.pid + " " + app.processName +
15876                " adj " + app.curAdj + ": " + app.adjType);
15877            app.setAdj = app.curAdj;
15878        }
15879
15880        if (app.setSchedGroup != app.curSchedGroup) {
15881            app.setSchedGroup = app.curSchedGroup;
15882            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15883                    "Setting process group of " + app.processName
15884                    + " to " + app.curSchedGroup);
15885            if (app.waitingToKill != null &&
15886                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15887                killUnneededProcessLocked(app, app.waitingToKill);
15888                success = false;
15889            } else {
15890                if (true) {
15891                    long oldId = Binder.clearCallingIdentity();
15892                    try {
15893                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15894                    } catch (Exception e) {
15895                        Slog.w(TAG, "Failed setting process group of " + app.pid
15896                                + " to " + app.curSchedGroup);
15897                        e.printStackTrace();
15898                    } finally {
15899                        Binder.restoreCallingIdentity(oldId);
15900                    }
15901                } else {
15902                    if (app.thread != null) {
15903                        try {
15904                            app.thread.setSchedulingGroup(app.curSchedGroup);
15905                        } catch (RemoteException e) {
15906                        }
15907                    }
15908                }
15909                Process.setSwappiness(app.pid,
15910                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15911            }
15912        }
15913        if (app.repForegroundActivities != app.foregroundActivities) {
15914            app.repForegroundActivities = app.foregroundActivities;
15915            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15916        }
15917        if (app.repProcState != app.curProcState) {
15918            app.repProcState = app.curProcState;
15919            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
15920            if (app.thread != null) {
15921                try {
15922                    if (false) {
15923                        //RuntimeException h = new RuntimeException("here");
15924                        Slog.i(TAG, "Sending new process state " + app.repProcState
15925                                + " to " + app /*, h*/);
15926                    }
15927                    app.thread.setProcessState(app.repProcState);
15928                } catch (RemoteException e) {
15929                }
15930            }
15931        }
15932        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15933                app.setProcState)) {
15934            app.lastStateTime = now;
15935            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15936                    isSleeping(), now);
15937            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15938                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15939                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15940                    + (app.nextPssTime-now) + ": " + app);
15941        } else {
15942            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15943                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15944                requestPssLocked(app, app.setProcState);
15945                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15946                        isSleeping(), now);
15947            } else if (false && DEBUG_PSS) {
15948                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15949            }
15950        }
15951        if (app.setProcState != app.curProcState) {
15952            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15953                    "Proc state change of " + app.processName
15954                    + " to " + app.curProcState);
15955            app.setProcState = app.curProcState;
15956            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15957                app.notCachedSinceIdle = false;
15958            }
15959            if (!doingAll) {
15960                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15961            } else {
15962                app.procStateChanged = true;
15963            }
15964        }
15965
15966        if (changes != 0) {
15967            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15968            int i = mPendingProcessChanges.size()-1;
15969            ProcessChangeItem item = null;
15970            while (i >= 0) {
15971                item = mPendingProcessChanges.get(i);
15972                if (item.pid == app.pid) {
15973                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15974                    break;
15975                }
15976                i--;
15977            }
15978            if (i < 0) {
15979                // No existing item in pending changes; need a new one.
15980                final int NA = mAvailProcessChanges.size();
15981                if (NA > 0) {
15982                    item = mAvailProcessChanges.remove(NA-1);
15983                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15984                } else {
15985                    item = new ProcessChangeItem();
15986                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15987                }
15988                item.changes = 0;
15989                item.pid = app.pid;
15990                item.uid = app.info.uid;
15991                if (mPendingProcessChanges.size() == 0) {
15992                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15993                            "*** Enqueueing dispatch processes changed!");
15994                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
15995                }
15996                mPendingProcessChanges.add(item);
15997            }
15998            item.changes |= changes;
15999            item.processState = app.repProcState;
16000            item.foregroundActivities = app.repForegroundActivities;
16001            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16002                    + Integer.toHexString(System.identityHashCode(item))
16003                    + " " + app.toShortString() + ": changes=" + item.changes
16004                    + " procState=" + item.processState
16005                    + " foreground=" + item.foregroundActivities
16006                    + " type=" + app.adjType + " source=" + app.adjSource
16007                    + " target=" + app.adjTarget);
16008        }
16009
16010        return success;
16011    }
16012
16013    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
16014        if (proc.thread != null && proc.baseProcessTracker != null) {
16015            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16016        }
16017    }
16018
16019    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16020            ProcessRecord TOP_APP, boolean doingAll, long now) {
16021        if (app.thread == null) {
16022            return false;
16023        }
16024
16025        final boolean wasKeeping = app.keeping;
16026
16027        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16028
16029        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now);
16030    }
16031
16032    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16033            boolean oomAdj) {
16034        if (isForeground != proc.foregroundServices) {
16035            proc.foregroundServices = isForeground;
16036            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16037                    proc.info.uid);
16038            if (isForeground) {
16039                if (curProcs == null) {
16040                    curProcs = new ArrayList<ProcessRecord>();
16041                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16042                }
16043                if (!curProcs.contains(proc)) {
16044                    curProcs.add(proc);
16045                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16046                            proc.info.packageName, proc.info.uid);
16047                }
16048            } else {
16049                if (curProcs != null) {
16050                    if (curProcs.remove(proc)) {
16051                        mBatteryStatsService.noteEvent(
16052                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16053                                proc.info.packageName, proc.info.uid);
16054                        if (curProcs.size() <= 0) {
16055                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16056                        }
16057                    }
16058                }
16059            }
16060            if (oomAdj) {
16061                updateOomAdjLocked();
16062            }
16063        }
16064    }
16065
16066    private final ActivityRecord resumedAppLocked() {
16067        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16068        String pkg;
16069        int uid;
16070        if (act != null && !act.sleeping) {
16071            pkg = act.packageName;
16072            uid = act.info.applicationInfo.uid;
16073        } else {
16074            pkg = null;
16075            uid = -1;
16076        }
16077        // Has the UID or resumed package name changed?
16078        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16079                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16080            if (mCurResumedPackage != null) {
16081                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16082                        mCurResumedPackage, mCurResumedUid);
16083            }
16084            mCurResumedPackage = pkg;
16085            mCurResumedUid = uid;
16086            if (mCurResumedPackage != null) {
16087                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16088                        mCurResumedPackage, mCurResumedUid);
16089            }
16090        }
16091        return act;
16092    }
16093
16094    final boolean updateOomAdjLocked(ProcessRecord app) {
16095        final ActivityRecord TOP_ACT = resumedAppLocked();
16096        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16097        final boolean wasCached = app.cached;
16098
16099        mAdjSeq++;
16100
16101        // This is the desired cached adjusment we want to tell it to use.
16102        // If our app is currently cached, we know it, and that is it.  Otherwise,
16103        // we don't know it yet, and it needs to now be cached we will then
16104        // need to do a complete oom adj.
16105        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16106                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16107        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16108                SystemClock.uptimeMillis());
16109        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16110            // Changed to/from cached state, so apps after it in the LRU
16111            // list may also be changed.
16112            updateOomAdjLocked();
16113        }
16114        return success;
16115    }
16116
16117    final void updateOomAdjLocked() {
16118        final ActivityRecord TOP_ACT = resumedAppLocked();
16119        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16120        final long now = SystemClock.uptimeMillis();
16121        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16122        final int N = mLruProcesses.size();
16123
16124        if (false) {
16125            RuntimeException e = new RuntimeException();
16126            e.fillInStackTrace();
16127            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16128        }
16129
16130        mAdjSeq++;
16131        mNewNumServiceProcs = 0;
16132        mNewNumAServiceProcs = 0;
16133
16134        final int emptyProcessLimit;
16135        final int cachedProcessLimit;
16136        if (mProcessLimit <= 0) {
16137            emptyProcessLimit = cachedProcessLimit = 0;
16138        } else if (mProcessLimit == 1) {
16139            emptyProcessLimit = 1;
16140            cachedProcessLimit = 0;
16141        } else {
16142            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16143            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16144        }
16145
16146        // Let's determine how many processes we have running vs.
16147        // how many slots we have for background processes; we may want
16148        // to put multiple processes in a slot of there are enough of
16149        // them.
16150        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16151                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16152        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16153        if (numEmptyProcs > cachedProcessLimit) {
16154            // If there are more empty processes than our limit on cached
16155            // processes, then use the cached process limit for the factor.
16156            // This ensures that the really old empty processes get pushed
16157            // down to the bottom, so if we are running low on memory we will
16158            // have a better chance at keeping around more cached processes
16159            // instead of a gazillion empty processes.
16160            numEmptyProcs = cachedProcessLimit;
16161        }
16162        int emptyFactor = numEmptyProcs/numSlots;
16163        if (emptyFactor < 1) emptyFactor = 1;
16164        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16165        if (cachedFactor < 1) cachedFactor = 1;
16166        int stepCached = 0;
16167        int stepEmpty = 0;
16168        int numCached = 0;
16169        int numEmpty = 0;
16170        int numTrimming = 0;
16171
16172        mNumNonCachedProcs = 0;
16173        mNumCachedHiddenProcs = 0;
16174
16175        // First update the OOM adjustment for each of the
16176        // application processes based on their current state.
16177        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16178        int nextCachedAdj = curCachedAdj+1;
16179        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16180        int nextEmptyAdj = curEmptyAdj+2;
16181        for (int i=N-1; i>=0; i--) {
16182            ProcessRecord app = mLruProcesses.get(i);
16183            if (!app.killedByAm && app.thread != null) {
16184                app.procStateChanged = false;
16185                final boolean wasKeeping = app.keeping;
16186                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16187
16188                // If we haven't yet assigned the final cached adj
16189                // to the process, do that now.
16190                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16191                    switch (app.curProcState) {
16192                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16193                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16194                            // This process is a cached process holding activities...
16195                            // assign it the next cached value for that type, and then
16196                            // step that cached level.
16197                            app.curRawAdj = curCachedAdj;
16198                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16199                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16200                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16201                                    + ")");
16202                            if (curCachedAdj != nextCachedAdj) {
16203                                stepCached++;
16204                                if (stepCached >= cachedFactor) {
16205                                    stepCached = 0;
16206                                    curCachedAdj = nextCachedAdj;
16207                                    nextCachedAdj += 2;
16208                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16209                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16210                                    }
16211                                }
16212                            }
16213                            break;
16214                        default:
16215                            // For everything else, assign next empty cached process
16216                            // level and bump that up.  Note that this means that
16217                            // long-running services that have dropped down to the
16218                            // cached level will be treated as empty (since their process
16219                            // state is still as a service), which is what we want.
16220                            app.curRawAdj = curEmptyAdj;
16221                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16222                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16223                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16224                                    + ")");
16225                            if (curEmptyAdj != nextEmptyAdj) {
16226                                stepEmpty++;
16227                                if (stepEmpty >= emptyFactor) {
16228                                    stepEmpty = 0;
16229                                    curEmptyAdj = nextEmptyAdj;
16230                                    nextEmptyAdj += 2;
16231                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16232                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16233                                    }
16234                                }
16235                            }
16236                            break;
16237                    }
16238                }
16239
16240                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now);
16241
16242                // Count the number of process types.
16243                switch (app.curProcState) {
16244                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16245                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16246                        mNumCachedHiddenProcs++;
16247                        numCached++;
16248                        if (numCached > cachedProcessLimit) {
16249                            killUnneededProcessLocked(app, "cached #" + numCached);
16250                        }
16251                        break;
16252                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16253                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16254                                && app.lastActivityTime < oldTime) {
16255                            killUnneededProcessLocked(app, "empty for "
16256                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16257                                    / 1000) + "s");
16258                        } else {
16259                            numEmpty++;
16260                            if (numEmpty > emptyProcessLimit) {
16261                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16262                            }
16263                        }
16264                        break;
16265                    default:
16266                        mNumNonCachedProcs++;
16267                        break;
16268                }
16269
16270                if (app.isolated && app.services.size() <= 0) {
16271                    // If this is an isolated process, and there are no
16272                    // services running in it, then the process is no longer
16273                    // needed.  We agressively kill these because we can by
16274                    // definition not re-use the same process again, and it is
16275                    // good to avoid having whatever code was running in them
16276                    // left sitting around after no longer needed.
16277                    killUnneededProcessLocked(app, "isolated not needed");
16278                }
16279
16280                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16281                        && !app.killedByAm) {
16282                    numTrimming++;
16283                }
16284            }
16285        }
16286
16287        mNumServiceProcs = mNewNumServiceProcs;
16288
16289        // Now determine the memory trimming level of background processes.
16290        // Unfortunately we need to start at the back of the list to do this
16291        // properly.  We only do this if the number of background apps we
16292        // are managing to keep around is less than half the maximum we desire;
16293        // if we are keeping a good number around, we'll let them use whatever
16294        // memory they want.
16295        final int numCachedAndEmpty = numCached + numEmpty;
16296        int memFactor;
16297        if (numCached <= ProcessList.TRIM_CACHED_APPS
16298                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16299            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16300                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16301            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16302                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16303            } else {
16304                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16305            }
16306        } else {
16307            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16308        }
16309        // We always allow the memory level to go up (better).  We only allow it to go
16310        // down if we are in a state where that is allowed, *and* the total number of processes
16311        // has gone down since last time.
16312        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16313                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16314                + " last=" + mLastNumProcesses);
16315        if (memFactor > mLastMemoryLevel) {
16316            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16317                memFactor = mLastMemoryLevel;
16318                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16319            }
16320        }
16321        mLastMemoryLevel = memFactor;
16322        mLastNumProcesses = mLruProcesses.size();
16323        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16324        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16325        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16326            if (mLowRamStartTime == 0) {
16327                mLowRamStartTime = now;
16328            }
16329            int step = 0;
16330            int fgTrimLevel;
16331            switch (memFactor) {
16332                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16333                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16334                    break;
16335                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16336                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16337                    break;
16338                default:
16339                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16340                    break;
16341            }
16342            int factor = numTrimming/3;
16343            int minFactor = 2;
16344            if (mHomeProcess != null) minFactor++;
16345            if (mPreviousProcess != null) minFactor++;
16346            if (factor < minFactor) factor = minFactor;
16347            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16348            for (int i=N-1; i>=0; i--) {
16349                ProcessRecord app = mLruProcesses.get(i);
16350                if (allChanged || app.procStateChanged) {
16351                    setProcessTrackerState(app, trackerMemFactor, now);
16352                    app.procStateChanged = false;
16353                }
16354                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16355                        && !app.killedByAm) {
16356                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16357                        try {
16358                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16359                                    "Trimming memory of " + app.processName
16360                                    + " to " + curLevel);
16361                            app.thread.scheduleTrimMemory(curLevel);
16362                        } catch (RemoteException e) {
16363                        }
16364                        if (false) {
16365                            // For now we won't do this; our memory trimming seems
16366                            // to be good enough at this point that destroying
16367                            // activities causes more harm than good.
16368                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16369                                    && app != mHomeProcess && app != mPreviousProcess) {
16370                                // Need to do this on its own message because the stack may not
16371                                // be in a consistent state at this point.
16372                                // For these apps we will also finish their activities
16373                                // to help them free memory.
16374                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16375                            }
16376                        }
16377                    }
16378                    app.trimMemoryLevel = curLevel;
16379                    step++;
16380                    if (step >= factor) {
16381                        step = 0;
16382                        switch (curLevel) {
16383                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16384                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16385                                break;
16386                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16387                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16388                                break;
16389                        }
16390                    }
16391                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16392                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16393                            && app.thread != null) {
16394                        try {
16395                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16396                                    "Trimming memory of heavy-weight " + app.processName
16397                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16398                            app.thread.scheduleTrimMemory(
16399                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16400                        } catch (RemoteException e) {
16401                        }
16402                    }
16403                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16404                } else {
16405                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16406                            || app.systemNoUi) && app.pendingUiClean) {
16407                        // If this application is now in the background and it
16408                        // had done UI, then give it the special trim level to
16409                        // have it free UI resources.
16410                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16411                        if (app.trimMemoryLevel < level && app.thread != null) {
16412                            try {
16413                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16414                                        "Trimming memory of bg-ui " + app.processName
16415                                        + " to " + level);
16416                                app.thread.scheduleTrimMemory(level);
16417                            } catch (RemoteException e) {
16418                            }
16419                        }
16420                        app.pendingUiClean = false;
16421                    }
16422                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16423                        try {
16424                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16425                                    "Trimming memory of fg " + app.processName
16426                                    + " to " + fgTrimLevel);
16427                            app.thread.scheduleTrimMemory(fgTrimLevel);
16428                        } catch (RemoteException e) {
16429                        }
16430                    }
16431                    app.trimMemoryLevel = fgTrimLevel;
16432                }
16433            }
16434        } else {
16435            if (mLowRamStartTime != 0) {
16436                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16437                mLowRamStartTime = 0;
16438            }
16439            for (int i=N-1; i>=0; i--) {
16440                ProcessRecord app = mLruProcesses.get(i);
16441                if (allChanged || app.procStateChanged) {
16442                    setProcessTrackerState(app, trackerMemFactor, now);
16443                    app.procStateChanged = false;
16444                }
16445                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16446                        || app.systemNoUi) && app.pendingUiClean) {
16447                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16448                            && app.thread != null) {
16449                        try {
16450                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16451                                    "Trimming memory of ui hidden " + app.processName
16452                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16453                            app.thread.scheduleTrimMemory(
16454                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16455                        } catch (RemoteException e) {
16456                        }
16457                    }
16458                    app.pendingUiClean = false;
16459                }
16460                app.trimMemoryLevel = 0;
16461            }
16462        }
16463
16464        if (mAlwaysFinishActivities) {
16465            // Need to do this on its own message because the stack may not
16466            // be in a consistent state at this point.
16467            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16468        }
16469
16470        if (allChanged) {
16471            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16472        }
16473
16474        if (mProcessStats.shouldWriteNowLocked(now)) {
16475            mHandler.post(new Runnable() {
16476                @Override public void run() {
16477                    synchronized (ActivityManagerService.this) {
16478                        mProcessStats.writeStateAsyncLocked();
16479                    }
16480                }
16481            });
16482        }
16483
16484        if (DEBUG_OOM_ADJ) {
16485            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16486        }
16487    }
16488
16489    final void trimApplications() {
16490        synchronized (this) {
16491            int i;
16492
16493            // First remove any unused application processes whose package
16494            // has been removed.
16495            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16496                final ProcessRecord app = mRemovedProcesses.get(i);
16497                if (app.activities.size() == 0
16498                        && app.curReceiver == null && app.services.size() == 0) {
16499                    Slog.i(
16500                        TAG, "Exiting empty application process "
16501                        + app.processName + " ("
16502                        + (app.thread != null ? app.thread.asBinder() : null)
16503                        + ")\n");
16504                    if (app.pid > 0 && app.pid != MY_PID) {
16505                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16506                                app.processName, app.setAdj, "empty");
16507                        app.killedByAm = true;
16508                        Process.killProcessQuiet(app.pid);
16509                    } else {
16510                        try {
16511                            app.thread.scheduleExit();
16512                        } catch (Exception e) {
16513                            // Ignore exceptions.
16514                        }
16515                    }
16516                    cleanUpApplicationRecordLocked(app, false, true, -1);
16517                    mRemovedProcesses.remove(i);
16518
16519                    if (app.persistent) {
16520                        if (app.persistent) {
16521                            addAppLocked(app.info, false, null /* ABI override */);
16522                        }
16523                    }
16524                }
16525            }
16526
16527            // Now update the oom adj for all processes.
16528            updateOomAdjLocked();
16529        }
16530    }
16531
16532    /** This method sends the specified signal to each of the persistent apps */
16533    public void signalPersistentProcesses(int sig) throws RemoteException {
16534        if (sig != Process.SIGNAL_USR1) {
16535            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16536        }
16537
16538        synchronized (this) {
16539            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16540                    != PackageManager.PERMISSION_GRANTED) {
16541                throw new SecurityException("Requires permission "
16542                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16543            }
16544
16545            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16546                ProcessRecord r = mLruProcesses.get(i);
16547                if (r.thread != null && r.persistent) {
16548                    Process.sendSignal(r.pid, sig);
16549                }
16550            }
16551        }
16552    }
16553
16554    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16555        if (proc == null || proc == mProfileProc) {
16556            proc = mProfileProc;
16557            path = mProfileFile;
16558            profileType = mProfileType;
16559            clearProfilerLocked();
16560        }
16561        if (proc == null) {
16562            return;
16563        }
16564        try {
16565            proc.thread.profilerControl(false, path, null, profileType);
16566        } catch (RemoteException e) {
16567            throw new IllegalStateException("Process disappeared");
16568        }
16569    }
16570
16571    private void clearProfilerLocked() {
16572        if (mProfileFd != null) {
16573            try {
16574                mProfileFd.close();
16575            } catch (IOException e) {
16576            }
16577        }
16578        mProfileApp = null;
16579        mProfileProc = null;
16580        mProfileFile = null;
16581        mProfileType = 0;
16582        mAutoStopProfiler = false;
16583    }
16584
16585    public boolean profileControl(String process, int userId, boolean start,
16586            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16587
16588        try {
16589            synchronized (this) {
16590                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16591                // its own permission.
16592                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16593                        != PackageManager.PERMISSION_GRANTED) {
16594                    throw new SecurityException("Requires permission "
16595                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16596                }
16597
16598                if (start && fd == null) {
16599                    throw new IllegalArgumentException("null fd");
16600                }
16601
16602                ProcessRecord proc = null;
16603                if (process != null) {
16604                    proc = findProcessLocked(process, userId, "profileControl");
16605                }
16606
16607                if (start && (proc == null || proc.thread == null)) {
16608                    throw new IllegalArgumentException("Unknown process: " + process);
16609                }
16610
16611                if (start) {
16612                    stopProfilerLocked(null, null, 0);
16613                    setProfileApp(proc.info, proc.processName, path, fd, false);
16614                    mProfileProc = proc;
16615                    mProfileType = profileType;
16616                    try {
16617                        fd = fd.dup();
16618                    } catch (IOException e) {
16619                        fd = null;
16620                    }
16621                    proc.thread.profilerControl(start, path, fd, profileType);
16622                    fd = null;
16623                    mProfileFd = null;
16624                } else {
16625                    stopProfilerLocked(proc, path, profileType);
16626                    if (fd != null) {
16627                        try {
16628                            fd.close();
16629                        } catch (IOException e) {
16630                        }
16631                    }
16632                }
16633
16634                return true;
16635            }
16636        } catch (RemoteException e) {
16637            throw new IllegalStateException("Process disappeared");
16638        } finally {
16639            if (fd != null) {
16640                try {
16641                    fd.close();
16642                } catch (IOException e) {
16643                }
16644            }
16645        }
16646    }
16647
16648    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16649        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16650                userId, true, true, callName, null);
16651        ProcessRecord proc = null;
16652        try {
16653            int pid = Integer.parseInt(process);
16654            synchronized (mPidsSelfLocked) {
16655                proc = mPidsSelfLocked.get(pid);
16656            }
16657        } catch (NumberFormatException e) {
16658        }
16659
16660        if (proc == null) {
16661            ArrayMap<String, SparseArray<ProcessRecord>> all
16662                    = mProcessNames.getMap();
16663            SparseArray<ProcessRecord> procs = all.get(process);
16664            if (procs != null && procs.size() > 0) {
16665                proc = procs.valueAt(0);
16666                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16667                    for (int i=1; i<procs.size(); i++) {
16668                        ProcessRecord thisProc = procs.valueAt(i);
16669                        if (thisProc.userId == userId) {
16670                            proc = thisProc;
16671                            break;
16672                        }
16673                    }
16674                }
16675            }
16676        }
16677
16678        return proc;
16679    }
16680
16681    public boolean dumpHeap(String process, int userId, boolean managed,
16682            String path, ParcelFileDescriptor fd) throws RemoteException {
16683
16684        try {
16685            synchronized (this) {
16686                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16687                // its own permission (same as profileControl).
16688                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16689                        != PackageManager.PERMISSION_GRANTED) {
16690                    throw new SecurityException("Requires permission "
16691                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16692                }
16693
16694                if (fd == null) {
16695                    throw new IllegalArgumentException("null fd");
16696                }
16697
16698                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16699                if (proc == null || proc.thread == null) {
16700                    throw new IllegalArgumentException("Unknown process: " + process);
16701                }
16702
16703                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16704                if (!isDebuggable) {
16705                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16706                        throw new SecurityException("Process not debuggable: " + proc);
16707                    }
16708                }
16709
16710                proc.thread.dumpHeap(managed, path, fd);
16711                fd = null;
16712                return true;
16713            }
16714        } catch (RemoteException e) {
16715            throw new IllegalStateException("Process disappeared");
16716        } finally {
16717            if (fd != null) {
16718                try {
16719                    fd.close();
16720                } catch (IOException e) {
16721                }
16722            }
16723        }
16724    }
16725
16726    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16727    public void monitor() {
16728        synchronized (this) { }
16729    }
16730
16731    void onCoreSettingsChange(Bundle settings) {
16732        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16733            ProcessRecord processRecord = mLruProcesses.get(i);
16734            try {
16735                if (processRecord.thread != null) {
16736                    processRecord.thread.setCoreSettings(settings);
16737                }
16738            } catch (RemoteException re) {
16739                /* ignore */
16740            }
16741        }
16742    }
16743
16744    // Multi-user methods
16745
16746    /**
16747     * Start user, if its not already running, but don't bring it to foreground.
16748     */
16749    @Override
16750    public boolean startUserInBackground(final int userId) {
16751        return startUser(userId, /* foreground */ false);
16752    }
16753
16754    /**
16755     * Refreshes the list of users related to the current user when either a
16756     * user switch happens or when a new related user is started in the
16757     * background.
16758     */
16759    private void updateCurrentProfileIdsLocked() {
16760        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16761                mCurrentUserId, false /* enabledOnly */);
16762        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16763        for (int i = 0; i < currentProfileIds.length; i++) {
16764            currentProfileIds[i] = profiles.get(i).id;
16765        }
16766        mCurrentProfileIds = currentProfileIds;
16767    }
16768
16769    private Set getProfileIdsLocked(int userId) {
16770        Set userIds = new HashSet<Integer>();
16771        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16772                userId, false /* enabledOnly */);
16773        for (UserInfo user : profiles) {
16774            userIds.add(Integer.valueOf(user.id));
16775        }
16776        return userIds;
16777    }
16778
16779    @Override
16780    public boolean switchUser(final int userId) {
16781        return startUser(userId, /* foregound */ true);
16782    }
16783
16784    private boolean startUser(final int userId, boolean foreground) {
16785        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
16786                != PackageManager.PERMISSION_GRANTED) {
16787            String msg = "Permission Denial: switchUser() from pid="
16788                    + Binder.getCallingPid()
16789                    + ", uid=" + Binder.getCallingUid()
16790                    + " requires " + INTERACT_ACROSS_USERS_FULL;
16791            Slog.w(TAG, msg);
16792            throw new SecurityException(msg);
16793        }
16794
16795        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16796
16797        final long ident = Binder.clearCallingIdentity();
16798        try {
16799            synchronized (this) {
16800                final int oldUserId = mCurrentUserId;
16801                if (oldUserId == userId) {
16802                    return true;
16803                }
16804
16805                mStackSupervisor.setLockTaskModeLocked(null, false);
16806
16807                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16808                if (userInfo == null) {
16809                    Slog.w(TAG, "No user info for user #" + userId);
16810                    return false;
16811                }
16812
16813                if (foreground) {
16814                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16815                            R.anim.screen_user_enter);
16816                }
16817
16818                boolean needStart = false;
16819
16820                // If the user we are switching to is not currently started, then
16821                // we need to start it now.
16822                if (mStartedUsers.get(userId) == null) {
16823                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16824                    updateStartedUserArrayLocked();
16825                    needStart = true;
16826                }
16827
16828                final Integer userIdInt = Integer.valueOf(userId);
16829                mUserLru.remove(userIdInt);
16830                mUserLru.add(userIdInt);
16831
16832                if (foreground) {
16833                    mCurrentUserId = userId;
16834                    updateCurrentProfileIdsLocked();
16835                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16836                    // Once the internal notion of the active user has switched, we lock the device
16837                    // with the option to show the user switcher on the keyguard.
16838                    mWindowManager.lockNow(null);
16839                } else {
16840                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16841                    updateCurrentProfileIdsLocked();
16842                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16843                    mUserLru.remove(currentUserIdInt);
16844                    mUserLru.add(currentUserIdInt);
16845                }
16846
16847                final UserStartedState uss = mStartedUsers.get(userId);
16848
16849                // Make sure user is in the started state.  If it is currently
16850                // stopping, we need to knock that off.
16851                if (uss.mState == UserStartedState.STATE_STOPPING) {
16852                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16853                    // so we can just fairly silently bring the user back from
16854                    // the almost-dead.
16855                    uss.mState = UserStartedState.STATE_RUNNING;
16856                    updateStartedUserArrayLocked();
16857                    needStart = true;
16858                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16859                    // This means ACTION_SHUTDOWN has been sent, so we will
16860                    // need to treat this as a new boot of the user.
16861                    uss.mState = UserStartedState.STATE_BOOTING;
16862                    updateStartedUserArrayLocked();
16863                    needStart = true;
16864                }
16865
16866                if (uss.mState == UserStartedState.STATE_BOOTING) {
16867                    // Booting up a new user, need to tell system services about it.
16868                    // Note that this is on the same handler as scheduling of broadcasts,
16869                    // which is important because it needs to go first.
16870                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
16871                }
16872
16873                if (foreground) {
16874                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId));
16875                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16876                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16877                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16878                            oldUserId, userId, uss));
16879                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16880                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16881                }
16882
16883                if (needStart) {
16884                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16885                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16886                            | Intent.FLAG_RECEIVER_FOREGROUND);
16887                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16888                    broadcastIntentLocked(null, null, intent,
16889                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16890                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16891                }
16892
16893                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16894                    if (userId != UserHandle.USER_OWNER) {
16895                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16896                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16897                        broadcastIntentLocked(null, null, intent, null,
16898                                new IIntentReceiver.Stub() {
16899                                    public void performReceive(Intent intent, int resultCode,
16900                                            String data, Bundle extras, boolean ordered,
16901                                            boolean sticky, int sendingUser) {
16902                                        userInitialized(uss, userId);
16903                                    }
16904                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16905                                true, false, MY_PID, Process.SYSTEM_UID,
16906                                userId);
16907                        uss.initializing = true;
16908                    } else {
16909                        getUserManagerLocked().makeInitialized(userInfo.id);
16910                    }
16911                }
16912
16913                if (foreground) {
16914                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16915                    if (homeInFront) {
16916                        startHomeActivityLocked(userId);
16917                    } else {
16918                        mStackSupervisor.resumeTopActivitiesLocked();
16919                    }
16920                    EventLogTags.writeAmSwitchUser(userId);
16921                    getUserManagerLocked().userForeground(userId);
16922                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16923                } else {
16924                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
16925                }
16926
16927                if (needStart) {
16928                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16929                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16930                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16931                    broadcastIntentLocked(null, null, intent,
16932                            null, new IIntentReceiver.Stub() {
16933                                @Override
16934                                public void performReceive(Intent intent, int resultCode, String data,
16935                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16936                                        throws RemoteException {
16937                                }
16938                            }, 0, null, null,
16939                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16940                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16941                }
16942            }
16943        } finally {
16944            Binder.restoreCallingIdentity(ident);
16945        }
16946
16947        return true;
16948    }
16949
16950    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16951        long ident = Binder.clearCallingIdentity();
16952        try {
16953            Intent intent;
16954            if (oldUserId >= 0) {
16955                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16956                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16957                        | Intent.FLAG_RECEIVER_FOREGROUND);
16958                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16959                broadcastIntentLocked(null, null, intent,
16960                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16961                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16962            }
16963            if (newUserId >= 0) {
16964                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16965                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16966                        | Intent.FLAG_RECEIVER_FOREGROUND);
16967                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16968                broadcastIntentLocked(null, null, intent,
16969                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16970                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16971                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16972                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16973                        | Intent.FLAG_RECEIVER_FOREGROUND);
16974                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16975                broadcastIntentLocked(null, null, intent,
16976                        null, null, 0, null, null,
16977                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16978                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16979            }
16980        } finally {
16981            Binder.restoreCallingIdentity(ident);
16982        }
16983    }
16984
16985    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16986            final int newUserId) {
16987        final int N = mUserSwitchObservers.beginBroadcast();
16988        if (N > 0) {
16989            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16990                int mCount = 0;
16991                @Override
16992                public void sendResult(Bundle data) throws RemoteException {
16993                    synchronized (ActivityManagerService.this) {
16994                        if (mCurUserSwitchCallback == this) {
16995                            mCount++;
16996                            if (mCount == N) {
16997                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
16998                            }
16999                        }
17000                    }
17001                }
17002            };
17003            synchronized (this) {
17004                uss.switching = true;
17005                mCurUserSwitchCallback = callback;
17006            }
17007            for (int i=0; i<N; i++) {
17008                try {
17009                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17010                            newUserId, callback);
17011                } catch (RemoteException e) {
17012                }
17013            }
17014        } else {
17015            synchronized (this) {
17016                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17017            }
17018        }
17019        mUserSwitchObservers.finishBroadcast();
17020    }
17021
17022    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17023        synchronized (this) {
17024            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17025            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17026        }
17027    }
17028
17029    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17030        mCurUserSwitchCallback = null;
17031        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17032        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17033                oldUserId, newUserId, uss));
17034    }
17035
17036    void userInitialized(UserStartedState uss, int newUserId) {
17037        completeSwitchAndInitalize(uss, newUserId, true, false);
17038    }
17039
17040    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17041        completeSwitchAndInitalize(uss, newUserId, false, true);
17042    }
17043
17044    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17045            boolean clearInitializing, boolean clearSwitching) {
17046        boolean unfrozen = false;
17047        synchronized (this) {
17048            if (clearInitializing) {
17049                uss.initializing = false;
17050                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17051            }
17052            if (clearSwitching) {
17053                uss.switching = false;
17054            }
17055            if (!uss.switching && !uss.initializing) {
17056                mWindowManager.stopFreezingScreen();
17057                unfrozen = true;
17058            }
17059        }
17060        if (unfrozen) {
17061            final int N = mUserSwitchObservers.beginBroadcast();
17062            for (int i=0; i<N; i++) {
17063                try {
17064                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17065                } catch (RemoteException e) {
17066                }
17067            }
17068            mUserSwitchObservers.finishBroadcast();
17069        }
17070    }
17071
17072    void scheduleStartProfilesLocked() {
17073        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17074            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17075                    DateUtils.SECOND_IN_MILLIS);
17076        }
17077    }
17078
17079    void startProfilesLocked() {
17080        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17081        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17082                mCurrentUserId, false /* enabledOnly */);
17083        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17084        for (UserInfo user : profiles) {
17085            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17086                    && user.id != mCurrentUserId) {
17087                toStart.add(user);
17088            }
17089        }
17090        final int n = toStart.size();
17091        int i = 0;
17092        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17093            startUserInBackground(toStart.get(i).id);
17094        }
17095        if (i < n) {
17096            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17097        }
17098    }
17099
17100    void finishUserBoot(UserStartedState uss) {
17101        synchronized (this) {
17102            if (uss.mState == UserStartedState.STATE_BOOTING
17103                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17104                uss.mState = UserStartedState.STATE_RUNNING;
17105                final int userId = uss.mHandle.getIdentifier();
17106                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17107                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17108                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17109                broadcastIntentLocked(null, null, intent,
17110                        null, null, 0, null, null,
17111                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17112                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17113            }
17114        }
17115    }
17116
17117    void finishUserSwitch(UserStartedState uss) {
17118        synchronized (this) {
17119            finishUserBoot(uss);
17120
17121            startProfilesLocked();
17122
17123            int num = mUserLru.size();
17124            int i = 0;
17125            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17126                Integer oldUserId = mUserLru.get(i);
17127                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17128                if (oldUss == null) {
17129                    // Shouldn't happen, but be sane if it does.
17130                    mUserLru.remove(i);
17131                    num--;
17132                    continue;
17133                }
17134                if (oldUss.mState == UserStartedState.STATE_STOPPING
17135                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17136                    // This user is already stopping, doesn't count.
17137                    num--;
17138                    i++;
17139                    continue;
17140                }
17141                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17142                    // Owner and current can't be stopped, but count as running.
17143                    i++;
17144                    continue;
17145                }
17146                // This is a user to be stopped.
17147                stopUserLocked(oldUserId, null);
17148                num--;
17149                i++;
17150            }
17151        }
17152    }
17153
17154    @Override
17155    public int stopUser(final int userId, final IStopUserCallback callback) {
17156        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17157                != PackageManager.PERMISSION_GRANTED) {
17158            String msg = "Permission Denial: switchUser() from pid="
17159                    + Binder.getCallingPid()
17160                    + ", uid=" + Binder.getCallingUid()
17161                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17162            Slog.w(TAG, msg);
17163            throw new SecurityException(msg);
17164        }
17165        if (userId <= 0) {
17166            throw new IllegalArgumentException("Can't stop primary user " + userId);
17167        }
17168        synchronized (this) {
17169            return stopUserLocked(userId, callback);
17170        }
17171    }
17172
17173    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17174        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17175        if (mCurrentUserId == userId) {
17176            return ActivityManager.USER_OP_IS_CURRENT;
17177        }
17178
17179        final UserStartedState uss = mStartedUsers.get(userId);
17180        if (uss == null) {
17181            // User is not started, nothing to do...  but we do need to
17182            // callback if requested.
17183            if (callback != null) {
17184                mHandler.post(new Runnable() {
17185                    @Override
17186                    public void run() {
17187                        try {
17188                            callback.userStopped(userId);
17189                        } catch (RemoteException e) {
17190                        }
17191                    }
17192                });
17193            }
17194            return ActivityManager.USER_OP_SUCCESS;
17195        }
17196
17197        if (callback != null) {
17198            uss.mStopCallbacks.add(callback);
17199        }
17200
17201        if (uss.mState != UserStartedState.STATE_STOPPING
17202                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17203            uss.mState = UserStartedState.STATE_STOPPING;
17204            updateStartedUserArrayLocked();
17205
17206            long ident = Binder.clearCallingIdentity();
17207            try {
17208                // We are going to broadcast ACTION_USER_STOPPING and then
17209                // once that is done send a final ACTION_SHUTDOWN and then
17210                // stop the user.
17211                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17212                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17213                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17214                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17215                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17216                // This is the result receiver for the final shutdown broadcast.
17217                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17218                    @Override
17219                    public void performReceive(Intent intent, int resultCode, String data,
17220                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17221                        finishUserStop(uss);
17222                    }
17223                };
17224                // This is the result receiver for the initial stopping broadcast.
17225                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17226                    @Override
17227                    public void performReceive(Intent intent, int resultCode, String data,
17228                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17229                        // On to the next.
17230                        synchronized (ActivityManagerService.this) {
17231                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17232                                // Whoops, we are being started back up.  Abort, abort!
17233                                return;
17234                            }
17235                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17236                        }
17237                        mSystemServiceManager.stopUser(userId);
17238                        broadcastIntentLocked(null, null, shutdownIntent,
17239                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17240                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17241                    }
17242                };
17243                // Kick things off.
17244                broadcastIntentLocked(null, null, stoppingIntent,
17245                        null, stoppingReceiver, 0, null, null,
17246                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17247                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17248            } finally {
17249                Binder.restoreCallingIdentity(ident);
17250            }
17251        }
17252
17253        return ActivityManager.USER_OP_SUCCESS;
17254    }
17255
17256    void finishUserStop(UserStartedState uss) {
17257        final int userId = uss.mHandle.getIdentifier();
17258        boolean stopped;
17259        ArrayList<IStopUserCallback> callbacks;
17260        synchronized (this) {
17261            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17262            if (mStartedUsers.get(userId) != uss) {
17263                stopped = false;
17264            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17265                stopped = false;
17266            } else {
17267                stopped = true;
17268                // User can no longer run.
17269                mStartedUsers.remove(userId);
17270                mUserLru.remove(Integer.valueOf(userId));
17271                updateStartedUserArrayLocked();
17272
17273                // Clean up all state and processes associated with the user.
17274                // Kill all the processes for the user.
17275                forceStopUserLocked(userId, "finish user");
17276            }
17277        }
17278
17279        for (int i=0; i<callbacks.size(); i++) {
17280            try {
17281                if (stopped) callbacks.get(i).userStopped(userId);
17282                else callbacks.get(i).userStopAborted(userId);
17283            } catch (RemoteException e) {
17284            }
17285        }
17286
17287        if (stopped) {
17288            mSystemServiceManager.cleanupUser(userId);
17289            synchronized (this) {
17290                mStackSupervisor.removeUserLocked(userId);
17291            }
17292        }
17293    }
17294
17295    @Override
17296    public UserInfo getCurrentUser() {
17297        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17298                != PackageManager.PERMISSION_GRANTED) && (
17299                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17300                != PackageManager.PERMISSION_GRANTED)) {
17301            String msg = "Permission Denial: getCurrentUser() from pid="
17302                    + Binder.getCallingPid()
17303                    + ", uid=" + Binder.getCallingUid()
17304                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17305            Slog.w(TAG, msg);
17306            throw new SecurityException(msg);
17307        }
17308        synchronized (this) {
17309            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17310        }
17311    }
17312
17313    int getCurrentUserIdLocked() {
17314        return mCurrentUserId;
17315    }
17316
17317    @Override
17318    public boolean isUserRunning(int userId, boolean orStopped) {
17319        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17320                != PackageManager.PERMISSION_GRANTED) {
17321            String msg = "Permission Denial: isUserRunning() from pid="
17322                    + Binder.getCallingPid()
17323                    + ", uid=" + Binder.getCallingUid()
17324                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17325            Slog.w(TAG, msg);
17326            throw new SecurityException(msg);
17327        }
17328        synchronized (this) {
17329            return isUserRunningLocked(userId, orStopped);
17330        }
17331    }
17332
17333    boolean isUserRunningLocked(int userId, boolean orStopped) {
17334        UserStartedState state = mStartedUsers.get(userId);
17335        if (state == null) {
17336            return false;
17337        }
17338        if (orStopped) {
17339            return true;
17340        }
17341        return state.mState != UserStartedState.STATE_STOPPING
17342                && state.mState != UserStartedState.STATE_SHUTDOWN;
17343    }
17344
17345    @Override
17346    public int[] getRunningUserIds() {
17347        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17348                != PackageManager.PERMISSION_GRANTED) {
17349            String msg = "Permission Denial: isUserRunning() from pid="
17350                    + Binder.getCallingPid()
17351                    + ", uid=" + Binder.getCallingUid()
17352                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17353            Slog.w(TAG, msg);
17354            throw new SecurityException(msg);
17355        }
17356        synchronized (this) {
17357            return mStartedUserArray;
17358        }
17359    }
17360
17361    private void updateStartedUserArrayLocked() {
17362        int num = 0;
17363        for (int i=0; i<mStartedUsers.size();  i++) {
17364            UserStartedState uss = mStartedUsers.valueAt(i);
17365            // This list does not include stopping users.
17366            if (uss.mState != UserStartedState.STATE_STOPPING
17367                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17368                num++;
17369            }
17370        }
17371        mStartedUserArray = new int[num];
17372        num = 0;
17373        for (int i=0; i<mStartedUsers.size();  i++) {
17374            UserStartedState uss = mStartedUsers.valueAt(i);
17375            if (uss.mState != UserStartedState.STATE_STOPPING
17376                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17377                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17378                num++;
17379            }
17380        }
17381    }
17382
17383    @Override
17384    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17385        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17386                != PackageManager.PERMISSION_GRANTED) {
17387            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17388                    + Binder.getCallingPid()
17389                    + ", uid=" + Binder.getCallingUid()
17390                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17391            Slog.w(TAG, msg);
17392            throw new SecurityException(msg);
17393        }
17394
17395        mUserSwitchObservers.register(observer);
17396    }
17397
17398    @Override
17399    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17400        mUserSwitchObservers.unregister(observer);
17401    }
17402
17403    private boolean userExists(int userId) {
17404        if (userId == 0) {
17405            return true;
17406        }
17407        UserManagerService ums = getUserManagerLocked();
17408        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17409    }
17410
17411    int[] getUsersLocked() {
17412        UserManagerService ums = getUserManagerLocked();
17413        return ums != null ? ums.getUserIds() : new int[] { 0 };
17414    }
17415
17416    UserManagerService getUserManagerLocked() {
17417        if (mUserManager == null) {
17418            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17419            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17420        }
17421        return mUserManager;
17422    }
17423
17424    private int applyUserId(int uid, int userId) {
17425        return UserHandle.getUid(userId, uid);
17426    }
17427
17428    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17429        if (info == null) return null;
17430        ApplicationInfo newInfo = new ApplicationInfo(info);
17431        newInfo.uid = applyUserId(info.uid, userId);
17432        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17433                + info.packageName;
17434        return newInfo;
17435    }
17436
17437    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17438        if (aInfo == null
17439                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17440            return aInfo;
17441        }
17442
17443        ActivityInfo info = new ActivityInfo(aInfo);
17444        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17445        return info;
17446    }
17447
17448    private final class LocalService extends ActivityManagerInternal {
17449        @Override
17450        public void goingToSleep() {
17451            ActivityManagerService.this.goingToSleep();
17452        }
17453
17454        @Override
17455        public void wakingUp() {
17456            ActivityManagerService.this.wakingUp();
17457        }
17458    }
17459
17460    /**
17461     * An implementation of IAppTask, that allows an app to manage its own tasks via
17462     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17463     * only the process that calls getAppTasks() can call the AppTask methods.
17464     */
17465    class AppTaskImpl extends IAppTask.Stub {
17466        private int mTaskId;
17467        private int mCallingUid;
17468
17469        public AppTaskImpl(int taskId, int callingUid) {
17470            mTaskId = taskId;
17471            mCallingUid = callingUid;
17472        }
17473
17474        @Override
17475        public void finishAndRemoveTask() {
17476            // Ensure that we are called from the same process that created this AppTask
17477            if (mCallingUid != Binder.getCallingUid()) {
17478                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17479                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17480                return;
17481            }
17482
17483            synchronized (ActivityManagerService.this) {
17484                long origId = Binder.clearCallingIdentity();
17485                try {
17486                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17487                    if (tr != null) {
17488                        // Only kill the process if we are not a new document
17489                        int flags = tr.getBaseIntent().getFlags();
17490                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17491                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17492                        removeTaskByIdLocked(mTaskId,
17493                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17494                    }
17495                } finally {
17496                    Binder.restoreCallingIdentity(origId);
17497                }
17498            }
17499        }
17500
17501        @Override
17502        public ActivityManager.RecentTaskInfo getTaskInfo() {
17503            // Ensure that we are called from the same process that created this AppTask
17504            if (mCallingUid != Binder.getCallingUid()) {
17505                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17506                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17507                return null;
17508            }
17509
17510            synchronized (ActivityManagerService.this) {
17511                long origId = Binder.clearCallingIdentity();
17512                try {
17513                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17514                    if (tr != null) {
17515                        return createRecentTaskInfoFromTaskRecord(tr);
17516                    }
17517                } finally {
17518                    Binder.restoreCallingIdentity(origId);
17519                }
17520                return null;
17521            }
17522        }
17523    }
17524}
17525