ActivityManagerService.java revision 80f74b544975900fa69fa078d424fa5cde9ad5c7
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        rti.lastActiveTime = tr.lastActiveTime;
7240        return rti;
7241    }
7242
7243    @Override
7244    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
7245            int flags, int userId) {
7246        final int callingUid = Binder.getCallingUid();
7247        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7248                false, true, "getRecentTasks", null);
7249
7250        synchronized (this) {
7251            final boolean allowed = checkCallingPermission(
7252                    android.Manifest.permission.GET_TASKS)
7253                    == PackageManager.PERMISSION_GRANTED;
7254            if (!allowed) {
7255                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7256                        + " does not hold GET_TASKS; limiting output");
7257            }
7258            final boolean detailed = checkCallingPermission(
7259                    android.Manifest.permission.GET_DETAILED_TASKS)
7260                    == PackageManager.PERMISSION_GRANTED;
7261
7262            IPackageManager pm = AppGlobals.getPackageManager();
7263
7264            final int N = mRecentTasks.size();
7265            ArrayList<ActivityManager.RecentTaskInfo> res
7266                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7267                            maxNum < N ? maxNum : N);
7268
7269            final Set<Integer> includedUsers;
7270            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
7271                includedUsers = getProfileIdsLocked(userId);
7272            } else {
7273                includedUsers = new HashSet<Integer>();
7274            }
7275            includedUsers.add(Integer.valueOf(userId));
7276            for (int i=0; i<N && maxNum > 0; i++) {
7277                TaskRecord tr = mRecentTasks.get(i);
7278                // Only add calling user or related users recent tasks
7279                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7280
7281                // Return the entry if desired by the caller.  We always return
7282                // the first entry, because callers always expect this to be the
7283                // foreground app.  We may filter others if the caller has
7284                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7285                // we should exclude the entry.
7286
7287                if (i == 0
7288                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
7289                        || (tr.intent == null)
7290                        || ((tr.intent.getFlags()
7291                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
7292                    if (!allowed) {
7293                        // If the caller doesn't have the GET_TASKS permission, then only
7294                        // allow them to see a small subset of tasks -- their own and home.
7295                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7296                            continue;
7297                        }
7298                    }
7299                    if (tr.intent != null &&
7300                            (tr.intent.getFlags() & Intent.FLAG_ACTIVITY_AUTO_REMOVE_FROM_RECENTS)
7301                            != 0 && tr.getTopActivity() == null) {
7302                        // Don't include auto remove tasks that are finished or finishing.
7303                        continue;
7304                    }
7305
7306                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7307                    if (!detailed) {
7308                        rti.baseIntent.replaceExtras((Bundle)null);
7309                    }
7310
7311                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7312                        // Check whether this activity is currently available.
7313                        try {
7314                            if (rti.origActivity != null) {
7315                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7316                                        == null) {
7317                                    continue;
7318                                }
7319                            } else if (rti.baseIntent != null) {
7320                                if (pm.queryIntentActivities(rti.baseIntent,
7321                                        null, 0, userId) == null) {
7322                                    continue;
7323                                }
7324                            }
7325                        } catch (RemoteException e) {
7326                            // Will never happen.
7327                        }
7328                    }
7329
7330                    res.add(rti);
7331                    maxNum--;
7332                }
7333            }
7334            return res;
7335        }
7336    }
7337
7338    private TaskRecord recentTaskForIdLocked(int id) {
7339        final int N = mRecentTasks.size();
7340            for (int i=0; i<N; i++) {
7341                TaskRecord tr = mRecentTasks.get(i);
7342                if (tr.taskId == id) {
7343                    return tr;
7344                }
7345            }
7346            return null;
7347    }
7348
7349    @Override
7350    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
7351        synchronized (this) {
7352            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7353                    "getTaskThumbnails()");
7354            TaskRecord tr = recentTaskForIdLocked(id);
7355            if (tr != null) {
7356                return tr.getTaskThumbnailsLocked();
7357            }
7358        }
7359        return null;
7360    }
7361
7362    @Override
7363    public Bitmap getTaskTopThumbnail(int id) {
7364        synchronized (this) {
7365            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7366                    "getTaskTopThumbnail()");
7367            TaskRecord tr = recentTaskForIdLocked(id);
7368            if (tr != null) {
7369                return tr.getTaskTopThumbnailLocked();
7370            }
7371        }
7372        return null;
7373    }
7374
7375    @Override
7376    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7377        synchronized (this) {
7378            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7379            if (r != null) {
7380                r.taskDescription = td;
7381                r.task.updateTaskDescription();
7382            }
7383        }
7384    }
7385
7386    @Override
7387    public boolean removeSubTask(int taskId, int subTaskIndex) {
7388        synchronized (this) {
7389            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7390                    "removeSubTask()");
7391            long ident = Binder.clearCallingIdentity();
7392            try {
7393                TaskRecord tr = recentTaskForIdLocked(taskId);
7394                if (tr != null) {
7395                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
7396                }
7397                return false;
7398            } finally {
7399                Binder.restoreCallingIdentity(ident);
7400            }
7401        }
7402    }
7403
7404    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7405        if (!pr.killedByAm) {
7406            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7407            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7408                    pr.processName, pr.setAdj, reason);
7409            pr.killedByAm = true;
7410            Process.killProcessQuiet(pr.pid);
7411        }
7412    }
7413
7414    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7415        tr.disposeThumbnail();
7416        mRecentTasks.remove(tr);
7417        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7418        Intent baseIntent = new Intent(
7419                tr.intent != null ? tr.intent : tr.affinityIntent);
7420        ComponentName component = baseIntent.getComponent();
7421        if (component == null) {
7422            Slog.w(TAG, "Now component for base intent of task: " + tr);
7423            return;
7424        }
7425
7426        // Find any running services associated with this app.
7427        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7428
7429        if (killProcesses) {
7430            // Find any running processes associated with this app.
7431            final String pkg = component.getPackageName();
7432            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7433            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7434            for (int i=0; i<pmap.size(); i++) {
7435                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7436                for (int j=0; j<uids.size(); j++) {
7437                    ProcessRecord proc = uids.valueAt(j);
7438                    if (proc.userId != tr.userId) {
7439                        continue;
7440                    }
7441                    if (!proc.pkgList.containsKey(pkg)) {
7442                        continue;
7443                    }
7444                    procs.add(proc);
7445                }
7446            }
7447
7448            // Kill the running processes.
7449            for (int i=0; i<procs.size(); i++) {
7450                ProcessRecord pr = procs.get(i);
7451                if (pr == mHomeProcess) {
7452                    // Don't kill the home process along with tasks from the same package.
7453                    continue;
7454                }
7455                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7456                    killUnneededProcessLocked(pr, "remove task");
7457                } else {
7458                    pr.waitingToKill = "remove task";
7459                }
7460            }
7461        }
7462    }
7463
7464    /**
7465     * Removes the task with the specified task id.
7466     *
7467     * @param taskId Identifier of the task to be removed.
7468     * @param flags Additional operational flags.  May be 0 or
7469     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7470     * @return Returns true if the given task was found and removed.
7471     */
7472    private boolean removeTaskByIdLocked(int taskId, int flags) {
7473        TaskRecord tr = recentTaskForIdLocked(taskId);
7474        if (tr != null) {
7475            tr.removeTaskActivitiesLocked(-1, false);
7476            cleanUpRemovedTaskLocked(tr, flags);
7477            if (tr.isPersistable) {
7478                notifyTaskPersisterLocked(tr, true);
7479            }
7480            return true;
7481        }
7482        return false;
7483    }
7484
7485    @Override
7486    public boolean removeTask(int taskId, int flags) {
7487        synchronized (this) {
7488            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7489                    "removeTask()");
7490            long ident = Binder.clearCallingIdentity();
7491            try {
7492                return removeTaskByIdLocked(taskId, flags);
7493            } finally {
7494                Binder.restoreCallingIdentity(ident);
7495            }
7496        }
7497    }
7498
7499    /**
7500     * TODO: Add mController hook
7501     */
7502    @Override
7503    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7504        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7505                "moveTaskToFront()");
7506
7507        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7508        synchronized(this) {
7509            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7510                    Binder.getCallingUid(), "Task to front")) {
7511                ActivityOptions.abort(options);
7512                return;
7513            }
7514            final long origId = Binder.clearCallingIdentity();
7515            try {
7516                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7517                if (task == null) {
7518                    return;
7519                }
7520                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7521                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7522                    return;
7523                }
7524                final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
7525                if (prev != null && prev.isRecentsActivity()) {
7526                    task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
7527                }
7528                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7529            } finally {
7530                Binder.restoreCallingIdentity(origId);
7531            }
7532            ActivityOptions.abort(options);
7533        }
7534    }
7535
7536    @Override
7537    public void moveTaskToBack(int taskId) {
7538        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7539                "moveTaskToBack()");
7540
7541        synchronized(this) {
7542            TaskRecord tr = recentTaskForIdLocked(taskId);
7543            if (tr != null) {
7544                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7545                ActivityStack stack = tr.stack;
7546                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7547                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7548                            Binder.getCallingUid(), "Task to back")) {
7549                        return;
7550                    }
7551                }
7552                final long origId = Binder.clearCallingIdentity();
7553                try {
7554                    stack.moveTaskToBackLocked(taskId, null);
7555                } finally {
7556                    Binder.restoreCallingIdentity(origId);
7557                }
7558            }
7559        }
7560    }
7561
7562    /**
7563     * Moves an activity, and all of the other activities within the same task, to the bottom
7564     * of the history stack.  The activity's order within the task is unchanged.
7565     *
7566     * @param token A reference to the activity we wish to move
7567     * @param nonRoot If false then this only works if the activity is the root
7568     *                of a task; if true it will work for any activity in a task.
7569     * @return Returns true if the move completed, false if not.
7570     */
7571    @Override
7572    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7573        enforceNotIsolatedCaller("moveActivityTaskToBack");
7574        synchronized(this) {
7575            final long origId = Binder.clearCallingIdentity();
7576            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7577            if (taskId >= 0) {
7578                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7579            }
7580            Binder.restoreCallingIdentity(origId);
7581        }
7582        return false;
7583    }
7584
7585    @Override
7586    public void moveTaskBackwards(int task) {
7587        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7588                "moveTaskBackwards()");
7589
7590        synchronized(this) {
7591            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7592                    Binder.getCallingUid(), "Task backwards")) {
7593                return;
7594            }
7595            final long origId = Binder.clearCallingIdentity();
7596            moveTaskBackwardsLocked(task);
7597            Binder.restoreCallingIdentity(origId);
7598        }
7599    }
7600
7601    private final void moveTaskBackwardsLocked(int task) {
7602        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7603    }
7604
7605    @Override
7606    public IBinder getHomeActivityToken() throws RemoteException {
7607        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7608                "getHomeActivityToken()");
7609        synchronized (this) {
7610            return mStackSupervisor.getHomeActivityToken();
7611        }
7612    }
7613
7614    @Override
7615    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7616            IActivityContainerCallback callback) throws RemoteException {
7617        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7618                "createActivityContainer()");
7619        synchronized (this) {
7620            if (parentActivityToken == null) {
7621                throw new IllegalArgumentException("parent token must not be null");
7622            }
7623            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7624            if (r == null) {
7625                return null;
7626            }
7627            if (callback == null) {
7628                throw new IllegalArgumentException("callback must not be null");
7629            }
7630            return mStackSupervisor.createActivityContainer(r, callback);
7631        }
7632    }
7633
7634    @Override
7635    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7636        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7637                "deleteActivityContainer()");
7638        synchronized (this) {
7639            mStackSupervisor.deleteActivityContainer(container);
7640        }
7641    }
7642
7643    @Override
7644    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7645            throws RemoteException {
7646        synchronized (this) {
7647            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7648            if (stack != null) {
7649                return stack.mActivityContainer;
7650            }
7651            return null;
7652        }
7653    }
7654
7655    @Override
7656    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7657        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7658                "moveTaskToStack()");
7659        if (stackId == HOME_STACK_ID) {
7660            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7661                    new RuntimeException("here").fillInStackTrace());
7662        }
7663        synchronized (this) {
7664            long ident = Binder.clearCallingIdentity();
7665            try {
7666                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7667                        + stackId + " toTop=" + toTop);
7668                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7669            } finally {
7670                Binder.restoreCallingIdentity(ident);
7671            }
7672        }
7673    }
7674
7675    @Override
7676    public void resizeStack(int stackBoxId, Rect bounds) {
7677        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7678                "resizeStackBox()");
7679        long ident = Binder.clearCallingIdentity();
7680        try {
7681            mWindowManager.resizeStack(stackBoxId, bounds);
7682        } finally {
7683            Binder.restoreCallingIdentity(ident);
7684        }
7685    }
7686
7687    @Override
7688    public List<StackInfo> getAllStackInfos() {
7689        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7690                "getAllStackInfos()");
7691        long ident = Binder.clearCallingIdentity();
7692        try {
7693            synchronized (this) {
7694                return mStackSupervisor.getAllStackInfosLocked();
7695            }
7696        } finally {
7697            Binder.restoreCallingIdentity(ident);
7698        }
7699    }
7700
7701    @Override
7702    public StackInfo getStackInfo(int stackId) {
7703        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7704                "getStackInfo()");
7705        long ident = Binder.clearCallingIdentity();
7706        try {
7707            synchronized (this) {
7708                return mStackSupervisor.getStackInfoLocked(stackId);
7709            }
7710        } finally {
7711            Binder.restoreCallingIdentity(ident);
7712        }
7713    }
7714
7715    @Override
7716    public boolean isInHomeStack(int taskId) {
7717        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7718                "getStackInfo()");
7719        long ident = Binder.clearCallingIdentity();
7720        try {
7721            synchronized (this) {
7722                TaskRecord tr = recentTaskForIdLocked(taskId);
7723                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7724            }
7725        } finally {
7726            Binder.restoreCallingIdentity(ident);
7727        }
7728    }
7729
7730    @Override
7731    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7732        synchronized(this) {
7733            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7734        }
7735    }
7736
7737    private boolean isLockTaskAuthorized(String pkg) {
7738        final DevicePolicyManager dpm = (DevicePolicyManager)
7739                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7740        try {
7741            int uid = mContext.getPackageManager().getPackageUid(pkg,
7742                    Binder.getCallingUserHandle().getIdentifier());
7743            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
7744        } catch (NameNotFoundException e) {
7745            return false;
7746        }
7747    }
7748
7749    void startLockTaskMode(TaskRecord task) {
7750        final String pkg;
7751        synchronized (this) {
7752            pkg = task.intent.getComponent().getPackageName();
7753        }
7754        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
7755        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
7756            final TaskRecord taskRecord = task;
7757            mHandler.post(new Runnable() {
7758                @Override
7759                public void run() {
7760                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
7761                }
7762            });
7763            return;
7764        }
7765        long ident = Binder.clearCallingIdentity();
7766        try {
7767            synchronized (this) {
7768                // Since we lost lock on task, make sure it is still there.
7769                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7770                if (task != null) {
7771                    if (!isSystemInitiated
7772                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
7773                        throw new IllegalArgumentException("Invalid task, not in foreground");
7774                    }
7775                    mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated);
7776                }
7777            }
7778        } finally {
7779            Binder.restoreCallingIdentity(ident);
7780        }
7781    }
7782
7783    @Override
7784    public void startLockTaskMode(int taskId) {
7785        final TaskRecord task;
7786        long ident = Binder.clearCallingIdentity();
7787        try {
7788            synchronized (this) {
7789                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7790            }
7791        } finally {
7792            Binder.restoreCallingIdentity(ident);
7793        }
7794        if (task != null) {
7795            startLockTaskMode(task);
7796        }
7797    }
7798
7799    @Override
7800    public void startLockTaskMode(IBinder token) {
7801        final TaskRecord task;
7802        long ident = Binder.clearCallingIdentity();
7803        try {
7804            synchronized (this) {
7805                final ActivityRecord r = ActivityRecord.forToken(token);
7806                if (r == null) {
7807                    return;
7808                }
7809                task = r.task;
7810            }
7811        } finally {
7812            Binder.restoreCallingIdentity(ident);
7813        }
7814        if (task != null) {
7815            startLockTaskMode(task);
7816        }
7817    }
7818
7819    @Override
7820    public void startLockTaskModeOnCurrent() throws RemoteException {
7821        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7822        ActivityRecord r = null;
7823        synchronized (this) {
7824            r = mStackSupervisor.topRunningActivityLocked();
7825        }
7826        startLockTaskMode(r.task);
7827    }
7828
7829    @Override
7830    public void stopLockTaskMode() {
7831        // Verify that the user matches the package of the intent for the TaskRecord
7832        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
7833        // and stopLockTaskMode.
7834        final int callingUid = Binder.getCallingUid();
7835        if (callingUid != Process.SYSTEM_UID) {
7836            try {
7837                String pkg =
7838                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
7839                int uid = mContext.getPackageManager().getPackageUid(pkg,
7840                        Binder.getCallingUserHandle().getIdentifier());
7841                if (uid != callingUid) {
7842                    throw new SecurityException("Invalid uid, expected " + uid);
7843                }
7844            } catch (NameNotFoundException e) {
7845                Log.d(TAG, "stopLockTaskMode " + e);
7846                return;
7847            }
7848        }
7849        long ident = Binder.clearCallingIdentity();
7850        try {
7851            Log.d(TAG, "stopLockTaskMode");
7852            // Stop lock task
7853            synchronized (this) {
7854                mStackSupervisor.setLockTaskModeLocked(null, false);
7855            }
7856        } finally {
7857            Binder.restoreCallingIdentity(ident);
7858        }
7859    }
7860
7861    @Override
7862    public void stopLockTaskModeOnCurrent() throws RemoteException {
7863        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7864        long ident = Binder.clearCallingIdentity();
7865        try {
7866            stopLockTaskMode();
7867        } finally {
7868            Binder.restoreCallingIdentity(ident);
7869        }
7870    }
7871
7872    @Override
7873    public boolean isInLockTaskMode() {
7874        synchronized (this) {
7875            return mStackSupervisor.isInLockTaskMode();
7876        }
7877    }
7878
7879    // =========================================================
7880    // CONTENT PROVIDERS
7881    // =========================================================
7882
7883    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7884        List<ProviderInfo> providers = null;
7885        try {
7886            providers = AppGlobals.getPackageManager().
7887                queryContentProviders(app.processName, app.uid,
7888                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7889        } catch (RemoteException ex) {
7890        }
7891        if (DEBUG_MU)
7892            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7893        int userId = app.userId;
7894        if (providers != null) {
7895            int N = providers.size();
7896            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7897            for (int i=0; i<N; i++) {
7898                ProviderInfo cpi =
7899                    (ProviderInfo)providers.get(i);
7900                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7901                        cpi.name, cpi.flags);
7902                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7903                    // This is a singleton provider, but a user besides the
7904                    // default user is asking to initialize a process it runs
7905                    // in...  well, no, it doesn't actually run in this process,
7906                    // it runs in the process of the default user.  Get rid of it.
7907                    providers.remove(i);
7908                    N--;
7909                    i--;
7910                    continue;
7911                }
7912
7913                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7914                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7915                if (cpr == null) {
7916                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7917                    mProviderMap.putProviderByClass(comp, cpr);
7918                }
7919                if (DEBUG_MU)
7920                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7921                app.pubProviders.put(cpi.name, cpr);
7922                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7923                    // Don't add this if it is a platform component that is marked
7924                    // to run in multiple processes, because this is actually
7925                    // part of the framework so doesn't make sense to track as a
7926                    // separate apk in the process.
7927                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
7928                            mProcessStats);
7929                }
7930                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7931            }
7932        }
7933        return providers;
7934    }
7935
7936    /**
7937     * Check if {@link ProcessRecord} has a possible chance at accessing the
7938     * given {@link ProviderInfo}. Final permission checking is always done
7939     * in {@link ContentProvider}.
7940     */
7941    private final String checkContentProviderPermissionLocked(
7942            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
7943        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7944        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7945        boolean checkedGrants = false;
7946        if (checkUser) {
7947            // Looking for cross-user grants before enforcing the typical cross-users permissions
7948            if (UserHandle.getUserId(callingUid) != userId) {
7949                if (checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
7950                    return null;
7951                }
7952                checkedGrants = true;
7953            }
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                String pprperm = pp.getReadPermission();
7975                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
7976                        cpi.applicationInfo.uid, cpi.exported)
7977                        == PackageManager.PERMISSION_GRANTED) {
7978                    return null;
7979                }
7980                String ppwperm = pp.getWritePermission();
7981                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
7982                        cpi.applicationInfo.uid, cpi.exported)
7983                        == PackageManager.PERMISSION_GRANTED) {
7984                    return null;
7985                }
7986            }
7987        }
7988        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
7989            return null;
7990        }
7991
7992        String msg;
7993        if (!cpi.exported) {
7994            msg = "Permission Denial: opening provider " + cpi.name
7995                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7996                    + ", uid=" + callingUid + ") that is not exported from uid "
7997                    + cpi.applicationInfo.uid;
7998        } else {
7999            msg = "Permission Denial: opening provider " + cpi.name
8000                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8001                    + ", uid=" + callingUid + ") requires "
8002                    + cpi.readPermission + " or " + cpi.writePermission;
8003        }
8004        Slog.w(TAG, msg);
8005        return msg;
8006    }
8007
8008    /**
8009     * Returns if the ContentProvider has granted a uri to callingUid
8010     */
8011    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8012        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8013        if (perms != null) {
8014            for (GrantUri grantUri : perms.keySet()) {
8015                if (grantUri.sourceUserId == userId || !checkUser) {
8016                    if (matchesProvider(grantUri.uri, cpi)) {
8017                        return true;
8018                    }
8019                }
8020            }
8021        }
8022        return false;
8023    }
8024
8025    /**
8026     * Returns true if the uri authority is one of the authorities specified in the provider.
8027     */
8028    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8029        String uriAuth = uri.getAuthority();
8030        String cpiAuth = cpi.authority;
8031        if (cpiAuth.indexOf(';') == -1) {
8032            return cpiAuth.equals(uriAuth);
8033        }
8034        String[] cpiAuths = cpiAuth.split(";");
8035        int length = cpiAuths.length;
8036        for (int i = 0; i < length; i++) {
8037            if (cpiAuths[i].equals(uriAuth)) return true;
8038        }
8039        return false;
8040    }
8041
8042    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8043            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8044        if (r != null) {
8045            for (int i=0; i<r.conProviders.size(); i++) {
8046                ContentProviderConnection conn = r.conProviders.get(i);
8047                if (conn.provider == cpr) {
8048                    if (DEBUG_PROVIDER) Slog.v(TAG,
8049                            "Adding provider requested by "
8050                            + r.processName + " from process "
8051                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8052                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8053                    if (stable) {
8054                        conn.stableCount++;
8055                        conn.numStableIncs++;
8056                    } else {
8057                        conn.unstableCount++;
8058                        conn.numUnstableIncs++;
8059                    }
8060                    return conn;
8061                }
8062            }
8063            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8064            if (stable) {
8065                conn.stableCount = 1;
8066                conn.numStableIncs = 1;
8067            } else {
8068                conn.unstableCount = 1;
8069                conn.numUnstableIncs = 1;
8070            }
8071            cpr.connections.add(conn);
8072            r.conProviders.add(conn);
8073            return conn;
8074        }
8075        cpr.addExternalProcessHandleLocked(externalProcessToken);
8076        return null;
8077    }
8078
8079    boolean decProviderCountLocked(ContentProviderConnection conn,
8080            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8081        if (conn != null) {
8082            cpr = conn.provider;
8083            if (DEBUG_PROVIDER) Slog.v(TAG,
8084                    "Removing provider requested by "
8085                    + conn.client.processName + " from process "
8086                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8087                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8088            if (stable) {
8089                conn.stableCount--;
8090            } else {
8091                conn.unstableCount--;
8092            }
8093            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8094                cpr.connections.remove(conn);
8095                conn.client.conProviders.remove(conn);
8096                return true;
8097            }
8098            return false;
8099        }
8100        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8101        return false;
8102    }
8103
8104    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8105            String name, IBinder token, boolean stable, int userId) {
8106        ContentProviderRecord cpr;
8107        ContentProviderConnection conn = null;
8108        ProviderInfo cpi = null;
8109
8110        synchronized(this) {
8111            ProcessRecord r = null;
8112            if (caller != null) {
8113                r = getRecordForAppLocked(caller);
8114                if (r == null) {
8115                    throw new SecurityException(
8116                            "Unable to find app for caller " + caller
8117                          + " (pid=" + Binder.getCallingPid()
8118                          + ") when getting content provider " + name);
8119                }
8120            }
8121
8122            boolean checkCrossUser = true;
8123
8124            // First check if this content provider has been published...
8125            cpr = mProviderMap.getProviderByName(name, userId);
8126            // If that didn't work, check if it exists for user 0 and then
8127            // verify that it's a singleton provider before using it.
8128            if (cpr == null && userId != UserHandle.USER_OWNER) {
8129                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8130                if (cpr != null) {
8131                    cpi = cpr.info;
8132                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8133                            cpi.name, cpi.flags)
8134                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8135                        userId = UserHandle.USER_OWNER;
8136                        checkCrossUser = false;
8137                    } else {
8138                        cpr = null;
8139                        cpi = null;
8140                    }
8141                }
8142            }
8143
8144            boolean providerRunning = cpr != null;
8145            if (providerRunning) {
8146                cpi = cpr.info;
8147                String msg;
8148                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8149                        != null) {
8150                    throw new SecurityException(msg);
8151                }
8152
8153                if (r != null && cpr.canRunHere(r)) {
8154                    // This provider has been published or is in the process
8155                    // of being published...  but it is also allowed to run
8156                    // in the caller's process, so don't make a connection
8157                    // and just let the caller instantiate its own instance.
8158                    ContentProviderHolder holder = cpr.newHolder(null);
8159                    // don't give caller the provider object, it needs
8160                    // to make its own.
8161                    holder.provider = null;
8162                    return holder;
8163                }
8164
8165                final long origId = Binder.clearCallingIdentity();
8166
8167                // In this case the provider instance already exists, so we can
8168                // return it right away.
8169                conn = incProviderCountLocked(r, cpr, token, stable);
8170                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8171                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8172                        // If this is a perceptible app accessing the provider,
8173                        // make sure to count it as being accessed and thus
8174                        // back up on the LRU list.  This is good because
8175                        // content providers are often expensive to start.
8176                        updateLruProcessLocked(cpr.proc, false, null);
8177                    }
8178                }
8179
8180                if (cpr.proc != null) {
8181                    if (false) {
8182                        if (cpr.name.flattenToShortString().equals(
8183                                "com.android.providers.calendar/.CalendarProvider2")) {
8184                            Slog.v(TAG, "****************** KILLING "
8185                                + cpr.name.flattenToShortString());
8186                            Process.killProcess(cpr.proc.pid);
8187                        }
8188                    }
8189                    boolean success = updateOomAdjLocked(cpr.proc);
8190                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8191                    // NOTE: there is still a race here where a signal could be
8192                    // pending on the process even though we managed to update its
8193                    // adj level.  Not sure what to do about this, but at least
8194                    // the race is now smaller.
8195                    if (!success) {
8196                        // Uh oh...  it looks like the provider's process
8197                        // has been killed on us.  We need to wait for a new
8198                        // process to be started, and make sure its death
8199                        // doesn't kill our process.
8200                        Slog.i(TAG,
8201                                "Existing provider " + cpr.name.flattenToShortString()
8202                                + " is crashing; detaching " + r);
8203                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8204                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8205                        if (!lastRef) {
8206                            // This wasn't the last ref our process had on
8207                            // the provider...  we have now been killed, bail.
8208                            return null;
8209                        }
8210                        providerRunning = false;
8211                        conn = null;
8212                    }
8213                }
8214
8215                Binder.restoreCallingIdentity(origId);
8216            }
8217
8218            boolean singleton;
8219            if (!providerRunning) {
8220                try {
8221                    cpi = AppGlobals.getPackageManager().
8222                        resolveContentProvider(name,
8223                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8224                } catch (RemoteException ex) {
8225                }
8226                if (cpi == null) {
8227                    return null;
8228                }
8229                // If the provider is a singleton AND
8230                // (it's a call within the same user || the provider is a
8231                // privileged app)
8232                // Then allow connecting to the singleton provider
8233                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8234                        cpi.name, cpi.flags)
8235                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8236                if (singleton) {
8237                    userId = UserHandle.USER_OWNER;
8238                }
8239                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8240
8241                String msg;
8242                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8243                        != null) {
8244                    throw new SecurityException(msg);
8245                }
8246
8247                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8248                        && !cpi.processName.equals("system")) {
8249                    // If this content provider does not run in the system
8250                    // process, and the system is not yet ready to run other
8251                    // processes, then fail fast instead of hanging.
8252                    throw new IllegalArgumentException(
8253                            "Attempt to launch content provider before system ready");
8254                }
8255
8256                // Make sure that the user who owns this provider is started.  If not,
8257                // we don't want to allow it to run.
8258                if (mStartedUsers.get(userId) == null) {
8259                    Slog.w(TAG, "Unable to launch app "
8260                            + cpi.applicationInfo.packageName + "/"
8261                            + cpi.applicationInfo.uid + " for provider "
8262                            + name + ": user " + userId + " is stopped");
8263                    return null;
8264                }
8265
8266                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8267                cpr = mProviderMap.getProviderByClass(comp, userId);
8268                final boolean firstClass = cpr == null;
8269                if (firstClass) {
8270                    try {
8271                        ApplicationInfo ai =
8272                            AppGlobals.getPackageManager().
8273                                getApplicationInfo(
8274                                        cpi.applicationInfo.packageName,
8275                                        STOCK_PM_FLAGS, userId);
8276                        if (ai == null) {
8277                            Slog.w(TAG, "No package info for content provider "
8278                                    + cpi.name);
8279                            return null;
8280                        }
8281                        ai = getAppInfoForUser(ai, userId);
8282                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8283                    } catch (RemoteException ex) {
8284                        // pm is in same process, this will never happen.
8285                    }
8286                }
8287
8288                if (r != null && cpr.canRunHere(r)) {
8289                    // If this is a multiprocess provider, then just return its
8290                    // info and allow the caller to instantiate it.  Only do
8291                    // this if the provider is the same user as the caller's
8292                    // process, or can run as root (so can be in any process).
8293                    return cpr.newHolder(null);
8294                }
8295
8296                if (DEBUG_PROVIDER) {
8297                    RuntimeException e = new RuntimeException("here");
8298                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8299                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8300                }
8301
8302                // This is single process, and our app is now connecting to it.
8303                // See if we are already in the process of launching this
8304                // provider.
8305                final int N = mLaunchingProviders.size();
8306                int i;
8307                for (i=0; i<N; i++) {
8308                    if (mLaunchingProviders.get(i) == cpr) {
8309                        break;
8310                    }
8311                }
8312
8313                // If the provider is not already being launched, then get it
8314                // started.
8315                if (i >= N) {
8316                    final long origId = Binder.clearCallingIdentity();
8317
8318                    try {
8319                        // Content provider is now in use, its package can't be stopped.
8320                        try {
8321                            AppGlobals.getPackageManager().setPackageStoppedState(
8322                                    cpr.appInfo.packageName, false, userId);
8323                        } catch (RemoteException e) {
8324                        } catch (IllegalArgumentException e) {
8325                            Slog.w(TAG, "Failed trying to unstop package "
8326                                    + cpr.appInfo.packageName + ": " + e);
8327                        }
8328
8329                        // Use existing process if already started
8330                        ProcessRecord proc = getProcessRecordLocked(
8331                                cpi.processName, cpr.appInfo.uid, false);
8332                        if (proc != null && proc.thread != null) {
8333                            if (DEBUG_PROVIDER) {
8334                                Slog.d(TAG, "Installing in existing process " + proc);
8335                            }
8336                            proc.pubProviders.put(cpi.name, cpr);
8337                            try {
8338                                proc.thread.scheduleInstallProvider(cpi);
8339                            } catch (RemoteException e) {
8340                            }
8341                        } else {
8342                            proc = startProcessLocked(cpi.processName,
8343                                    cpr.appInfo, false, 0, "content provider",
8344                                    new ComponentName(cpi.applicationInfo.packageName,
8345                                            cpi.name), false, false, false);
8346                            if (proc == null) {
8347                                Slog.w(TAG, "Unable to launch app "
8348                                        + cpi.applicationInfo.packageName + "/"
8349                                        + cpi.applicationInfo.uid + " for provider "
8350                                        + name + ": process is bad");
8351                                return null;
8352                            }
8353                        }
8354                        cpr.launchingApp = proc;
8355                        mLaunchingProviders.add(cpr);
8356                    } finally {
8357                        Binder.restoreCallingIdentity(origId);
8358                    }
8359                }
8360
8361                // Make sure the provider is published (the same provider class
8362                // may be published under multiple names).
8363                if (firstClass) {
8364                    mProviderMap.putProviderByClass(comp, cpr);
8365                }
8366
8367                mProviderMap.putProviderByName(name, cpr);
8368                conn = incProviderCountLocked(r, cpr, token, stable);
8369                if (conn != null) {
8370                    conn.waiting = true;
8371                }
8372            }
8373        }
8374
8375        // Wait for the provider to be published...
8376        synchronized (cpr) {
8377            while (cpr.provider == null) {
8378                if (cpr.launchingApp == null) {
8379                    Slog.w(TAG, "Unable to launch app "
8380                            + cpi.applicationInfo.packageName + "/"
8381                            + cpi.applicationInfo.uid + " for provider "
8382                            + name + ": launching app became null");
8383                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8384                            UserHandle.getUserId(cpi.applicationInfo.uid),
8385                            cpi.applicationInfo.packageName,
8386                            cpi.applicationInfo.uid, name);
8387                    return null;
8388                }
8389                try {
8390                    if (DEBUG_MU) {
8391                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8392                                + cpr.launchingApp);
8393                    }
8394                    if (conn != null) {
8395                        conn.waiting = true;
8396                    }
8397                    cpr.wait();
8398                } catch (InterruptedException ex) {
8399                } finally {
8400                    if (conn != null) {
8401                        conn.waiting = false;
8402                    }
8403                }
8404            }
8405        }
8406        return cpr != null ? cpr.newHolder(conn) : null;
8407    }
8408
8409    @Override
8410    public final ContentProviderHolder getContentProvider(
8411            IApplicationThread caller, String name, int userId, boolean stable) {
8412        enforceNotIsolatedCaller("getContentProvider");
8413        if (caller == null) {
8414            String msg = "null IApplicationThread when getting content provider "
8415                    + name;
8416            Slog.w(TAG, msg);
8417            throw new SecurityException(msg);
8418        }
8419        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8420        // with cross-user grant.
8421        return getContentProviderImpl(caller, name, null, stable, userId);
8422    }
8423
8424    public ContentProviderHolder getContentProviderExternal(
8425            String name, int userId, IBinder token) {
8426        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8427            "Do not have permission in call getContentProviderExternal()");
8428        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8429                false, true, "getContentProvider", null);
8430        return getContentProviderExternalUnchecked(name, token, userId);
8431    }
8432
8433    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8434            IBinder token, int userId) {
8435        return getContentProviderImpl(null, name, token, true, userId);
8436    }
8437
8438    /**
8439     * Drop a content provider from a ProcessRecord's bookkeeping
8440     */
8441    public void removeContentProvider(IBinder connection, boolean stable) {
8442        enforceNotIsolatedCaller("removeContentProvider");
8443        long ident = Binder.clearCallingIdentity();
8444        try {
8445            synchronized (this) {
8446                ContentProviderConnection conn;
8447                try {
8448                    conn = (ContentProviderConnection)connection;
8449                } catch (ClassCastException e) {
8450                    String msg ="removeContentProvider: " + connection
8451                            + " not a ContentProviderConnection";
8452                    Slog.w(TAG, msg);
8453                    throw new IllegalArgumentException(msg);
8454                }
8455                if (conn == null) {
8456                    throw new NullPointerException("connection is null");
8457                }
8458                if (decProviderCountLocked(conn, null, null, stable)) {
8459                    updateOomAdjLocked();
8460                }
8461            }
8462        } finally {
8463            Binder.restoreCallingIdentity(ident);
8464        }
8465    }
8466
8467    public void removeContentProviderExternal(String name, IBinder token) {
8468        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8469            "Do not have permission in call removeContentProviderExternal()");
8470        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8471    }
8472
8473    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8474        synchronized (this) {
8475            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8476            if(cpr == null) {
8477                //remove from mProvidersByClass
8478                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8479                return;
8480            }
8481
8482            //update content provider record entry info
8483            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8484            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8485            if (localCpr.hasExternalProcessHandles()) {
8486                if (localCpr.removeExternalProcessHandleLocked(token)) {
8487                    updateOomAdjLocked();
8488                } else {
8489                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8490                            + " with no external reference for token: "
8491                            + token + ".");
8492                }
8493            } else {
8494                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8495                        + " with no external references.");
8496            }
8497        }
8498    }
8499
8500    public final void publishContentProviders(IApplicationThread caller,
8501            List<ContentProviderHolder> providers) {
8502        if (providers == null) {
8503            return;
8504        }
8505
8506        enforceNotIsolatedCaller("publishContentProviders");
8507        synchronized (this) {
8508            final ProcessRecord r = getRecordForAppLocked(caller);
8509            if (DEBUG_MU)
8510                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8511            if (r == null) {
8512                throw new SecurityException(
8513                        "Unable to find app for caller " + caller
8514                      + " (pid=" + Binder.getCallingPid()
8515                      + ") when publishing content providers");
8516            }
8517
8518            final long origId = Binder.clearCallingIdentity();
8519
8520            final int N = providers.size();
8521            for (int i=0; i<N; i++) {
8522                ContentProviderHolder src = providers.get(i);
8523                if (src == null || src.info == null || src.provider == null) {
8524                    continue;
8525                }
8526                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8527                if (DEBUG_MU)
8528                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8529                if (dst != null) {
8530                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8531                    mProviderMap.putProviderByClass(comp, dst);
8532                    String names[] = dst.info.authority.split(";");
8533                    for (int j = 0; j < names.length; j++) {
8534                        mProviderMap.putProviderByName(names[j], dst);
8535                    }
8536
8537                    int NL = mLaunchingProviders.size();
8538                    int j;
8539                    for (j=0; j<NL; j++) {
8540                        if (mLaunchingProviders.get(j) == dst) {
8541                            mLaunchingProviders.remove(j);
8542                            j--;
8543                            NL--;
8544                        }
8545                    }
8546                    synchronized (dst) {
8547                        dst.provider = src.provider;
8548                        dst.proc = r;
8549                        dst.notifyAll();
8550                    }
8551                    updateOomAdjLocked(r);
8552                }
8553            }
8554
8555            Binder.restoreCallingIdentity(origId);
8556        }
8557    }
8558
8559    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8560        ContentProviderConnection conn;
8561        try {
8562            conn = (ContentProviderConnection)connection;
8563        } catch (ClassCastException e) {
8564            String msg ="refContentProvider: " + connection
8565                    + " not a ContentProviderConnection";
8566            Slog.w(TAG, msg);
8567            throw new IllegalArgumentException(msg);
8568        }
8569        if (conn == null) {
8570            throw new NullPointerException("connection is null");
8571        }
8572
8573        synchronized (this) {
8574            if (stable > 0) {
8575                conn.numStableIncs += stable;
8576            }
8577            stable = conn.stableCount + stable;
8578            if (stable < 0) {
8579                throw new IllegalStateException("stableCount < 0: " + stable);
8580            }
8581
8582            if (unstable > 0) {
8583                conn.numUnstableIncs += unstable;
8584            }
8585            unstable = conn.unstableCount + unstable;
8586            if (unstable < 0) {
8587                throw new IllegalStateException("unstableCount < 0: " + unstable);
8588            }
8589
8590            if ((stable+unstable) <= 0) {
8591                throw new IllegalStateException("ref counts can't go to zero here: stable="
8592                        + stable + " unstable=" + unstable);
8593            }
8594            conn.stableCount = stable;
8595            conn.unstableCount = unstable;
8596            return !conn.dead;
8597        }
8598    }
8599
8600    public void unstableProviderDied(IBinder connection) {
8601        ContentProviderConnection conn;
8602        try {
8603            conn = (ContentProviderConnection)connection;
8604        } catch (ClassCastException e) {
8605            String msg ="refContentProvider: " + connection
8606                    + " not a ContentProviderConnection";
8607            Slog.w(TAG, msg);
8608            throw new IllegalArgumentException(msg);
8609        }
8610        if (conn == null) {
8611            throw new NullPointerException("connection is null");
8612        }
8613
8614        // Safely retrieve the content provider associated with the connection.
8615        IContentProvider provider;
8616        synchronized (this) {
8617            provider = conn.provider.provider;
8618        }
8619
8620        if (provider == null) {
8621            // Um, yeah, we're way ahead of you.
8622            return;
8623        }
8624
8625        // Make sure the caller is being honest with us.
8626        if (provider.asBinder().pingBinder()) {
8627            // Er, no, still looks good to us.
8628            synchronized (this) {
8629                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8630                        + " says " + conn + " died, but we don't agree");
8631                return;
8632            }
8633        }
8634
8635        // Well look at that!  It's dead!
8636        synchronized (this) {
8637            if (conn.provider.provider != provider) {
8638                // But something changed...  good enough.
8639                return;
8640            }
8641
8642            ProcessRecord proc = conn.provider.proc;
8643            if (proc == null || proc.thread == null) {
8644                // Seems like the process is already cleaned up.
8645                return;
8646            }
8647
8648            // As far as we're concerned, this is just like receiving a
8649            // death notification...  just a bit prematurely.
8650            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8651                    + ") early provider death");
8652            final long ident = Binder.clearCallingIdentity();
8653            try {
8654                appDiedLocked(proc, proc.pid, proc.thread);
8655            } finally {
8656                Binder.restoreCallingIdentity(ident);
8657            }
8658        }
8659    }
8660
8661    @Override
8662    public void appNotRespondingViaProvider(IBinder connection) {
8663        enforceCallingPermission(
8664                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8665
8666        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8667        if (conn == null) {
8668            Slog.w(TAG, "ContentProviderConnection is null");
8669            return;
8670        }
8671
8672        final ProcessRecord host = conn.provider.proc;
8673        if (host == null) {
8674            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8675            return;
8676        }
8677
8678        final long token = Binder.clearCallingIdentity();
8679        try {
8680            appNotResponding(host, null, null, false, "ContentProvider not responding");
8681        } finally {
8682            Binder.restoreCallingIdentity(token);
8683        }
8684    }
8685
8686    public final void installSystemProviders() {
8687        List<ProviderInfo> providers;
8688        synchronized (this) {
8689            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8690            providers = generateApplicationProvidersLocked(app);
8691            if (providers != null) {
8692                for (int i=providers.size()-1; i>=0; i--) {
8693                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8694                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8695                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8696                                + ": not system .apk");
8697                        providers.remove(i);
8698                    }
8699                }
8700            }
8701        }
8702        if (providers != null) {
8703            mSystemThread.installSystemProviders(providers);
8704        }
8705
8706        mCoreSettingsObserver = new CoreSettingsObserver(this);
8707
8708        mUsageStatsService.monitorPackages();
8709    }
8710
8711    /**
8712     * Allows app to retrieve the MIME type of a URI without having permission
8713     * to access its content provider.
8714     *
8715     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8716     *
8717     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8718     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8719     */
8720    public String getProviderMimeType(Uri uri, int userId) {
8721        enforceNotIsolatedCaller("getProviderMimeType");
8722        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8723                userId, false, true, "getProviderMimeType", null);
8724        final String name = uri.getAuthority();
8725        final long ident = Binder.clearCallingIdentity();
8726        ContentProviderHolder holder = null;
8727
8728        try {
8729            holder = getContentProviderExternalUnchecked(name, null, userId);
8730            if (holder != null) {
8731                return holder.provider.getType(uri);
8732            }
8733        } catch (RemoteException e) {
8734            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8735            return null;
8736        } finally {
8737            if (holder != null) {
8738                removeContentProviderExternalUnchecked(name, null, userId);
8739            }
8740            Binder.restoreCallingIdentity(ident);
8741        }
8742
8743        return null;
8744    }
8745
8746    // =========================================================
8747    // GLOBAL MANAGEMENT
8748    // =========================================================
8749
8750    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8751            boolean isolated) {
8752        String proc = customProcess != null ? customProcess : info.processName;
8753        BatteryStatsImpl.Uid.Proc ps = null;
8754        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8755        int uid = info.uid;
8756        if (isolated) {
8757            int userId = UserHandle.getUserId(uid);
8758            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8759            while (true) {
8760                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8761                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8762                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8763                }
8764                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8765                mNextIsolatedProcessUid++;
8766                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8767                    // No process for this uid, use it.
8768                    break;
8769                }
8770                stepsLeft--;
8771                if (stepsLeft <= 0) {
8772                    return null;
8773                }
8774            }
8775        }
8776        return new ProcessRecord(stats, info, proc, uid);
8777    }
8778
8779    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
8780            String abiOverride) {
8781        ProcessRecord app;
8782        if (!isolated) {
8783            app = getProcessRecordLocked(info.processName, info.uid, true);
8784        } else {
8785            app = null;
8786        }
8787
8788        if (app == null) {
8789            app = newProcessRecordLocked(info, null, isolated);
8790            mProcessNames.put(info.processName, app.uid, app);
8791            if (isolated) {
8792                mIsolatedProcesses.put(app.uid, app);
8793            }
8794            updateLruProcessLocked(app, false, null);
8795            updateOomAdjLocked();
8796        }
8797
8798        // This package really, really can not be stopped.
8799        try {
8800            AppGlobals.getPackageManager().setPackageStoppedState(
8801                    info.packageName, false, UserHandle.getUserId(app.uid));
8802        } catch (RemoteException e) {
8803        } catch (IllegalArgumentException e) {
8804            Slog.w(TAG, "Failed trying to unstop package "
8805                    + info.packageName + ": " + e);
8806        }
8807
8808        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8809                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8810            app.persistent = true;
8811            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8812        }
8813        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8814            mPersistentStartingProcesses.add(app);
8815            startProcessLocked(app, "added application", app.processName,
8816                    abiOverride);
8817        }
8818
8819        return app;
8820    }
8821
8822    public void unhandledBack() {
8823        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8824                "unhandledBack()");
8825
8826        synchronized(this) {
8827            final long origId = Binder.clearCallingIdentity();
8828            try {
8829                getFocusedStack().unhandledBackLocked();
8830            } finally {
8831                Binder.restoreCallingIdentity(origId);
8832            }
8833        }
8834    }
8835
8836    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8837        enforceNotIsolatedCaller("openContentUri");
8838        final int userId = UserHandle.getCallingUserId();
8839        String name = uri.getAuthority();
8840        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8841        ParcelFileDescriptor pfd = null;
8842        if (cph != null) {
8843            // We record the binder invoker's uid in thread-local storage before
8844            // going to the content provider to open the file.  Later, in the code
8845            // that handles all permissions checks, we look for this uid and use
8846            // that rather than the Activity Manager's own uid.  The effect is that
8847            // we do the check against the caller's permissions even though it looks
8848            // to the content provider like the Activity Manager itself is making
8849            // the request.
8850            sCallerIdentity.set(new Identity(
8851                    Binder.getCallingPid(), Binder.getCallingUid()));
8852            try {
8853                pfd = cph.provider.openFile(null, uri, "r", null);
8854            } catch (FileNotFoundException e) {
8855                // do nothing; pfd will be returned null
8856            } finally {
8857                // Ensure that whatever happens, we clean up the identity state
8858                sCallerIdentity.remove();
8859            }
8860
8861            // We've got the fd now, so we're done with the provider.
8862            removeContentProviderExternalUnchecked(name, null, userId);
8863        } else {
8864            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8865        }
8866        return pfd;
8867    }
8868
8869    // Actually is sleeping or shutting down or whatever else in the future
8870    // is an inactive state.
8871    public boolean isSleepingOrShuttingDown() {
8872        return mSleeping || mShuttingDown;
8873    }
8874
8875    public boolean isSleeping() {
8876        return mSleeping;
8877    }
8878
8879    void goingToSleep() {
8880        synchronized(this) {
8881            mWentToSleep = true;
8882            updateEventDispatchingLocked();
8883            goToSleepIfNeededLocked();
8884        }
8885    }
8886
8887    void finishRunningVoiceLocked() {
8888        if (mRunningVoice) {
8889            mRunningVoice = false;
8890            goToSleepIfNeededLocked();
8891        }
8892    }
8893
8894    void goToSleepIfNeededLocked() {
8895        if (mWentToSleep && !mRunningVoice) {
8896            if (!mSleeping) {
8897                mSleeping = true;
8898                mStackSupervisor.goingToSleepLocked();
8899
8900                // Initialize the wake times of all processes.
8901                checkExcessivePowerUsageLocked(false);
8902                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8903                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8904                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8905            }
8906        }
8907    }
8908
8909    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
8910        mTaskPersister.notify(task, flush);
8911    }
8912
8913    @Override
8914    public boolean shutdown(int timeout) {
8915        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8916                != PackageManager.PERMISSION_GRANTED) {
8917            throw new SecurityException("Requires permission "
8918                    + android.Manifest.permission.SHUTDOWN);
8919        }
8920
8921        boolean timedout = false;
8922
8923        synchronized(this) {
8924            mShuttingDown = true;
8925            updateEventDispatchingLocked();
8926            timedout = mStackSupervisor.shutdownLocked(timeout);
8927        }
8928
8929        mAppOpsService.shutdown();
8930        mUsageStatsService.shutdown();
8931        mBatteryStatsService.shutdown();
8932        synchronized (this) {
8933            mProcessStats.shutdownLocked();
8934        }
8935        notifyTaskPersisterLocked(null, true);
8936
8937        return timedout;
8938    }
8939
8940    public final void activitySlept(IBinder token) {
8941        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8942
8943        final long origId = Binder.clearCallingIdentity();
8944
8945        synchronized (this) {
8946            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8947            if (r != null) {
8948                mStackSupervisor.activitySleptLocked(r);
8949            }
8950        }
8951
8952        Binder.restoreCallingIdentity(origId);
8953    }
8954
8955    void logLockScreen(String msg) {
8956        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8957                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8958                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8959                mStackSupervisor.mDismissKeyguardOnNextActivity);
8960    }
8961
8962    private void comeOutOfSleepIfNeededLocked() {
8963        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
8964            if (mSleeping) {
8965                mSleeping = false;
8966                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8967            }
8968        }
8969    }
8970
8971    void wakingUp() {
8972        synchronized(this) {
8973            mWentToSleep = false;
8974            updateEventDispatchingLocked();
8975            comeOutOfSleepIfNeededLocked();
8976        }
8977    }
8978
8979    void startRunningVoiceLocked() {
8980        if (!mRunningVoice) {
8981            mRunningVoice = true;
8982            comeOutOfSleepIfNeededLocked();
8983        }
8984    }
8985
8986    private void updateEventDispatchingLocked() {
8987        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8988    }
8989
8990    public void setLockScreenShown(boolean shown) {
8991        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8992                != PackageManager.PERMISSION_GRANTED) {
8993            throw new SecurityException("Requires permission "
8994                    + android.Manifest.permission.DEVICE_POWER);
8995        }
8996
8997        synchronized(this) {
8998            long ident = Binder.clearCallingIdentity();
8999            try {
9000                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9001                mLockScreenShown = shown;
9002                comeOutOfSleepIfNeededLocked();
9003            } finally {
9004                Binder.restoreCallingIdentity(ident);
9005            }
9006        }
9007    }
9008
9009    public void stopAppSwitches() {
9010        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9011                != PackageManager.PERMISSION_GRANTED) {
9012            throw new SecurityException("Requires permission "
9013                    + android.Manifest.permission.STOP_APP_SWITCHES);
9014        }
9015
9016        synchronized(this) {
9017            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9018                    + APP_SWITCH_DELAY_TIME;
9019            mDidAppSwitch = false;
9020            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9021            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9022            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9023        }
9024    }
9025
9026    public void resumeAppSwitches() {
9027        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9028                != PackageManager.PERMISSION_GRANTED) {
9029            throw new SecurityException("Requires permission "
9030                    + android.Manifest.permission.STOP_APP_SWITCHES);
9031        }
9032
9033        synchronized(this) {
9034            // Note that we don't execute any pending app switches... we will
9035            // let those wait until either the timeout, or the next start
9036            // activity request.
9037            mAppSwitchesAllowedTime = 0;
9038        }
9039    }
9040
9041    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9042            String name) {
9043        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9044            return true;
9045        }
9046
9047        final int perm = checkComponentPermission(
9048                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9049                callingUid, -1, true);
9050        if (perm == PackageManager.PERMISSION_GRANTED) {
9051            return true;
9052        }
9053
9054        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9055        return false;
9056    }
9057
9058    public void setDebugApp(String packageName, boolean waitForDebugger,
9059            boolean persistent) {
9060        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9061                "setDebugApp()");
9062
9063        long ident = Binder.clearCallingIdentity();
9064        try {
9065            // Note that this is not really thread safe if there are multiple
9066            // callers into it at the same time, but that's not a situation we
9067            // care about.
9068            if (persistent) {
9069                final ContentResolver resolver = mContext.getContentResolver();
9070                Settings.Global.putString(
9071                    resolver, Settings.Global.DEBUG_APP,
9072                    packageName);
9073                Settings.Global.putInt(
9074                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9075                    waitForDebugger ? 1 : 0);
9076            }
9077
9078            synchronized (this) {
9079                if (!persistent) {
9080                    mOrigDebugApp = mDebugApp;
9081                    mOrigWaitForDebugger = mWaitForDebugger;
9082                }
9083                mDebugApp = packageName;
9084                mWaitForDebugger = waitForDebugger;
9085                mDebugTransient = !persistent;
9086                if (packageName != null) {
9087                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9088                            false, UserHandle.USER_ALL, "set debug app");
9089                }
9090            }
9091        } finally {
9092            Binder.restoreCallingIdentity(ident);
9093        }
9094    }
9095
9096    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9097        synchronized (this) {
9098            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9099            if (!isDebuggable) {
9100                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9101                    throw new SecurityException("Process not debuggable: " + app.packageName);
9102                }
9103            }
9104
9105            mOpenGlTraceApp = processName;
9106        }
9107    }
9108
9109    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9110            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9111        synchronized (this) {
9112            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9113            if (!isDebuggable) {
9114                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9115                    throw new SecurityException("Process not debuggable: " + app.packageName);
9116                }
9117            }
9118            mProfileApp = processName;
9119            mProfileFile = profileFile;
9120            if (mProfileFd != null) {
9121                try {
9122                    mProfileFd.close();
9123                } catch (IOException e) {
9124                }
9125                mProfileFd = null;
9126            }
9127            mProfileFd = profileFd;
9128            mProfileType = 0;
9129            mAutoStopProfiler = autoStopProfiler;
9130        }
9131    }
9132
9133    @Override
9134    public void setAlwaysFinish(boolean enabled) {
9135        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9136                "setAlwaysFinish()");
9137
9138        Settings.Global.putInt(
9139                mContext.getContentResolver(),
9140                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9141
9142        synchronized (this) {
9143            mAlwaysFinishActivities = enabled;
9144        }
9145    }
9146
9147    @Override
9148    public void setActivityController(IActivityController controller) {
9149        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9150                "setActivityController()");
9151        synchronized (this) {
9152            mController = controller;
9153            Watchdog.getInstance().setActivityController(controller);
9154        }
9155    }
9156
9157    @Override
9158    public void setUserIsMonkey(boolean userIsMonkey) {
9159        synchronized (this) {
9160            synchronized (mPidsSelfLocked) {
9161                final int callingPid = Binder.getCallingPid();
9162                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9163                if (precessRecord == null) {
9164                    throw new SecurityException("Unknown process: " + callingPid);
9165                }
9166                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9167                    throw new SecurityException("Only an instrumentation process "
9168                            + "with a UiAutomation can call setUserIsMonkey");
9169                }
9170            }
9171            mUserIsMonkey = userIsMonkey;
9172        }
9173    }
9174
9175    @Override
9176    public boolean isUserAMonkey() {
9177        synchronized (this) {
9178            // If there is a controller also implies the user is a monkey.
9179            return (mUserIsMonkey || mController != null);
9180        }
9181    }
9182
9183    public void requestBugReport() {
9184        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9185        SystemProperties.set("ctl.start", "bugreport");
9186    }
9187
9188    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9189        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9190    }
9191
9192    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9193        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9194            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9195        }
9196        return KEY_DISPATCHING_TIMEOUT;
9197    }
9198
9199    @Override
9200    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9201        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9202                != PackageManager.PERMISSION_GRANTED) {
9203            throw new SecurityException("Requires permission "
9204                    + android.Manifest.permission.FILTER_EVENTS);
9205        }
9206        ProcessRecord proc;
9207        long timeout;
9208        synchronized (this) {
9209            synchronized (mPidsSelfLocked) {
9210                proc = mPidsSelfLocked.get(pid);
9211            }
9212            timeout = getInputDispatchingTimeoutLocked(proc);
9213        }
9214
9215        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9216            return -1;
9217        }
9218
9219        return timeout;
9220    }
9221
9222    /**
9223     * Handle input dispatching timeouts.
9224     * Returns whether input dispatching should be aborted or not.
9225     */
9226    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9227            final ActivityRecord activity, final ActivityRecord parent,
9228            final boolean aboveSystem, String reason) {
9229        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9230                != PackageManager.PERMISSION_GRANTED) {
9231            throw new SecurityException("Requires permission "
9232                    + android.Manifest.permission.FILTER_EVENTS);
9233        }
9234
9235        final String annotation;
9236        if (reason == null) {
9237            annotation = "Input dispatching timed out";
9238        } else {
9239            annotation = "Input dispatching timed out (" + reason + ")";
9240        }
9241
9242        if (proc != null) {
9243            synchronized (this) {
9244                if (proc.debugging) {
9245                    return false;
9246                }
9247
9248                if (mDidDexOpt) {
9249                    // Give more time since we were dexopting.
9250                    mDidDexOpt = false;
9251                    return false;
9252                }
9253
9254                if (proc.instrumentationClass != null) {
9255                    Bundle info = new Bundle();
9256                    info.putString("shortMsg", "keyDispatchingTimedOut");
9257                    info.putString("longMsg", annotation);
9258                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9259                    return true;
9260                }
9261            }
9262            mHandler.post(new Runnable() {
9263                @Override
9264                public void run() {
9265                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9266                }
9267            });
9268        }
9269
9270        return true;
9271    }
9272
9273    public Bundle getAssistContextExtras(int requestType) {
9274        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9275                "getAssistContextExtras()");
9276        PendingAssistExtras pae;
9277        Bundle extras = new Bundle();
9278        synchronized (this) {
9279            ActivityRecord activity = getFocusedStack().mResumedActivity;
9280            if (activity == null) {
9281                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9282                return null;
9283            }
9284            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9285            if (activity.app == null || activity.app.thread == null) {
9286                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9287                return extras;
9288            }
9289            if (activity.app.pid == Binder.getCallingPid()) {
9290                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9291                return extras;
9292            }
9293            pae = new PendingAssistExtras(activity);
9294            try {
9295                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9296                        requestType);
9297                mPendingAssistExtras.add(pae);
9298                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9299            } catch (RemoteException e) {
9300                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9301                return extras;
9302            }
9303        }
9304        synchronized (pae) {
9305            while (!pae.haveResult) {
9306                try {
9307                    pae.wait();
9308                } catch (InterruptedException e) {
9309                }
9310            }
9311            if (pae.result != null) {
9312                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9313            }
9314        }
9315        synchronized (this) {
9316            mPendingAssistExtras.remove(pae);
9317            mHandler.removeCallbacks(pae);
9318        }
9319        return extras;
9320    }
9321
9322    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9323        PendingAssistExtras pae = (PendingAssistExtras)token;
9324        synchronized (pae) {
9325            pae.result = extras;
9326            pae.haveResult = true;
9327            pae.notifyAll();
9328        }
9329    }
9330
9331    public void registerProcessObserver(IProcessObserver observer) {
9332        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9333                "registerProcessObserver()");
9334        synchronized (this) {
9335            mProcessObservers.register(observer);
9336        }
9337    }
9338
9339    @Override
9340    public void unregisterProcessObserver(IProcessObserver observer) {
9341        synchronized (this) {
9342            mProcessObservers.unregister(observer);
9343        }
9344    }
9345
9346    @Override
9347    public boolean convertFromTranslucent(IBinder token) {
9348        final long origId = Binder.clearCallingIdentity();
9349        try {
9350            synchronized (this) {
9351                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9352                if (r == null) {
9353                    return false;
9354                }
9355                if (r.changeWindowTranslucency(true)) {
9356                    mWindowManager.setAppFullscreen(token, true);
9357                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9358                    return true;
9359                }
9360                return false;
9361            }
9362        } finally {
9363            Binder.restoreCallingIdentity(origId);
9364        }
9365    }
9366
9367    @Override
9368    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9369        final long origId = Binder.clearCallingIdentity();
9370        try {
9371            synchronized (this) {
9372                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9373                if (r == null) {
9374                    return false;
9375                }
9376                if (r.changeWindowTranslucency(false)) {
9377                    r.task.stack.convertToTranslucent(r, options);
9378                    mWindowManager.setAppFullscreen(token, false);
9379                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9380                    return true;
9381                }
9382                return false;
9383            }
9384        } finally {
9385            Binder.restoreCallingIdentity(origId);
9386        }
9387    }
9388
9389    @Override
9390    public ActivityOptions getActivityOptions(IBinder token) {
9391        final long origId = Binder.clearCallingIdentity();
9392        try {
9393            synchronized (this) {
9394                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9395                if (r != null) {
9396                    final ActivityOptions activityOptions = r.pendingOptions;
9397                    r.pendingOptions = null;
9398                    return activityOptions;
9399                }
9400                return null;
9401            }
9402        } finally {
9403            Binder.restoreCallingIdentity(origId);
9404        }
9405    }
9406
9407    @Override
9408    public void setImmersive(IBinder token, boolean immersive) {
9409        synchronized(this) {
9410            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9411            if (r == null) {
9412                throw new IllegalArgumentException();
9413            }
9414            r.immersive = immersive;
9415
9416            // update associated state if we're frontmost
9417            if (r == mFocusedActivity) {
9418                if (DEBUG_IMMERSIVE) {
9419                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9420                }
9421                applyUpdateLockStateLocked(r);
9422            }
9423        }
9424    }
9425
9426    @Override
9427    public boolean isImmersive(IBinder token) {
9428        synchronized (this) {
9429            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9430            if (r == null) {
9431                throw new IllegalArgumentException();
9432            }
9433            return r.immersive;
9434        }
9435    }
9436
9437    public boolean isTopActivityImmersive() {
9438        enforceNotIsolatedCaller("startActivity");
9439        synchronized (this) {
9440            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9441            return (r != null) ? r.immersive : false;
9442        }
9443    }
9444
9445    public final void enterSafeMode() {
9446        synchronized(this) {
9447            // It only makes sense to do this before the system is ready
9448            // and started launching other packages.
9449            if (!mSystemReady) {
9450                try {
9451                    AppGlobals.getPackageManager().enterSafeMode();
9452                } catch (RemoteException e) {
9453                }
9454            }
9455
9456            mSafeMode = true;
9457        }
9458    }
9459
9460    public final void showSafeModeOverlay() {
9461        View v = LayoutInflater.from(mContext).inflate(
9462                com.android.internal.R.layout.safe_mode, null);
9463        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9464        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9465        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9466        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9467        lp.gravity = Gravity.BOTTOM | Gravity.START;
9468        lp.format = v.getBackground().getOpacity();
9469        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9470                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9471        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9472        ((WindowManager)mContext.getSystemService(
9473                Context.WINDOW_SERVICE)).addView(v, lp);
9474    }
9475
9476    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9477        if (!(sender instanceof PendingIntentRecord)) {
9478            return;
9479        }
9480        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9481        synchronized (stats) {
9482            if (mBatteryStatsService.isOnBattery()) {
9483                mBatteryStatsService.enforceCallingPermission();
9484                PendingIntentRecord rec = (PendingIntentRecord)sender;
9485                int MY_UID = Binder.getCallingUid();
9486                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9487                BatteryStatsImpl.Uid.Pkg pkg =
9488                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9489                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9490                pkg.incWakeupsLocked();
9491            }
9492        }
9493    }
9494
9495    public boolean killPids(int[] pids, String pReason, boolean secure) {
9496        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9497            throw new SecurityException("killPids only available to the system");
9498        }
9499        String reason = (pReason == null) ? "Unknown" : pReason;
9500        // XXX Note: don't acquire main activity lock here, because the window
9501        // manager calls in with its locks held.
9502
9503        boolean killed = false;
9504        synchronized (mPidsSelfLocked) {
9505            int[] types = new int[pids.length];
9506            int worstType = 0;
9507            for (int i=0; i<pids.length; i++) {
9508                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9509                if (proc != null) {
9510                    int type = proc.setAdj;
9511                    types[i] = type;
9512                    if (type > worstType) {
9513                        worstType = type;
9514                    }
9515                }
9516            }
9517
9518            // If the worst oom_adj is somewhere in the cached proc LRU range,
9519            // then constrain it so we will kill all cached procs.
9520            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9521                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9522                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9523            }
9524
9525            // If this is not a secure call, don't let it kill processes that
9526            // are important.
9527            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9528                worstType = ProcessList.SERVICE_ADJ;
9529            }
9530
9531            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9532            for (int i=0; i<pids.length; i++) {
9533                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9534                if (proc == null) {
9535                    continue;
9536                }
9537                int adj = proc.setAdj;
9538                if (adj >= worstType && !proc.killedByAm) {
9539                    killUnneededProcessLocked(proc, reason);
9540                    killed = true;
9541                }
9542            }
9543        }
9544        return killed;
9545    }
9546
9547    @Override
9548    public void killUid(int uid, String reason) {
9549        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9550            throw new SecurityException("killUid only available to the system");
9551        }
9552        synchronized (this) {
9553            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9554                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9555                    reason != null ? reason : "kill uid");
9556        }
9557    }
9558
9559    @Override
9560    public boolean killProcessesBelowForeground(String reason) {
9561        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9562            throw new SecurityException("killProcessesBelowForeground() only available to system");
9563        }
9564
9565        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9566    }
9567
9568    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9569        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9570            throw new SecurityException("killProcessesBelowAdj() only available to system");
9571        }
9572
9573        boolean killed = false;
9574        synchronized (mPidsSelfLocked) {
9575            final int size = mPidsSelfLocked.size();
9576            for (int i = 0; i < size; i++) {
9577                final int pid = mPidsSelfLocked.keyAt(i);
9578                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9579                if (proc == null) continue;
9580
9581                final int adj = proc.setAdj;
9582                if (adj > belowAdj && !proc.killedByAm) {
9583                    killUnneededProcessLocked(proc, reason);
9584                    killed = true;
9585                }
9586            }
9587        }
9588        return killed;
9589    }
9590
9591    @Override
9592    public void hang(final IBinder who, boolean allowRestart) {
9593        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9594                != PackageManager.PERMISSION_GRANTED) {
9595            throw new SecurityException("Requires permission "
9596                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9597        }
9598
9599        final IBinder.DeathRecipient death = new DeathRecipient() {
9600            @Override
9601            public void binderDied() {
9602                synchronized (this) {
9603                    notifyAll();
9604                }
9605            }
9606        };
9607
9608        try {
9609            who.linkToDeath(death, 0);
9610        } catch (RemoteException e) {
9611            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9612            return;
9613        }
9614
9615        synchronized (this) {
9616            Watchdog.getInstance().setAllowRestart(allowRestart);
9617            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9618            synchronized (death) {
9619                while (who.isBinderAlive()) {
9620                    try {
9621                        death.wait();
9622                    } catch (InterruptedException e) {
9623                    }
9624                }
9625            }
9626            Watchdog.getInstance().setAllowRestart(true);
9627        }
9628    }
9629
9630    @Override
9631    public void restart() {
9632        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9633                != PackageManager.PERMISSION_GRANTED) {
9634            throw new SecurityException("Requires permission "
9635                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9636        }
9637
9638        Log.i(TAG, "Sending shutdown broadcast...");
9639
9640        BroadcastReceiver br = new BroadcastReceiver() {
9641            @Override public void onReceive(Context context, Intent intent) {
9642                // Now the broadcast is done, finish up the low-level shutdown.
9643                Log.i(TAG, "Shutting down activity manager...");
9644                shutdown(10000);
9645                Log.i(TAG, "Shutdown complete, restarting!");
9646                Process.killProcess(Process.myPid());
9647                System.exit(10);
9648            }
9649        };
9650
9651        // First send the high-level shut down broadcast.
9652        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9653        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9654        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9655        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9656        mContext.sendOrderedBroadcastAsUser(intent,
9657                UserHandle.ALL, null, br, mHandler, 0, null, null);
9658        */
9659        br.onReceive(mContext, intent);
9660    }
9661
9662    private long getLowRamTimeSinceIdle(long now) {
9663        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9664    }
9665
9666    @Override
9667    public void performIdleMaintenance() {
9668        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9669                != PackageManager.PERMISSION_GRANTED) {
9670            throw new SecurityException("Requires permission "
9671                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9672        }
9673
9674        synchronized (this) {
9675            final long now = SystemClock.uptimeMillis();
9676            final long timeSinceLastIdle = now - mLastIdleTime;
9677            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9678            mLastIdleTime = now;
9679            mLowRamTimeSinceLastIdle = 0;
9680            if (mLowRamStartTime != 0) {
9681                mLowRamStartTime = now;
9682            }
9683
9684            StringBuilder sb = new StringBuilder(128);
9685            sb.append("Idle maintenance over ");
9686            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9687            sb.append(" low RAM for ");
9688            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9689            Slog.i(TAG, sb.toString());
9690
9691            // If at least 1/3 of our time since the last idle period has been spent
9692            // with RAM low, then we want to kill processes.
9693            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9694
9695            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9696                ProcessRecord proc = mLruProcesses.get(i);
9697                if (proc.notCachedSinceIdle) {
9698                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9699                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9700                        if (doKilling && proc.initialIdlePss != 0
9701                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9702                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9703                                    + " from " + proc.initialIdlePss + ")");
9704                        }
9705                    }
9706                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9707                    proc.notCachedSinceIdle = true;
9708                    proc.initialIdlePss = 0;
9709                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9710                            isSleeping(), now);
9711                }
9712            }
9713
9714            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9715            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9716        }
9717    }
9718
9719    private void retrieveSettings() {
9720        final ContentResolver resolver = mContext.getContentResolver();
9721        String debugApp = Settings.Global.getString(
9722            resolver, Settings.Global.DEBUG_APP);
9723        boolean waitForDebugger = Settings.Global.getInt(
9724            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9725        boolean alwaysFinishActivities = Settings.Global.getInt(
9726            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9727        boolean forceRtl = Settings.Global.getInt(
9728                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9729        // Transfer any global setting for forcing RTL layout, into a System Property
9730        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9731
9732        Configuration configuration = new Configuration();
9733        Settings.System.getConfiguration(resolver, configuration);
9734        if (forceRtl) {
9735            // This will take care of setting the correct layout direction flags
9736            configuration.setLayoutDirection(configuration.locale);
9737        }
9738
9739        synchronized (this) {
9740            mDebugApp = mOrigDebugApp = debugApp;
9741            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9742            mAlwaysFinishActivities = alwaysFinishActivities;
9743            // This happens before any activities are started, so we can
9744            // change mConfiguration in-place.
9745            updateConfigurationLocked(configuration, null, false, true);
9746            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9747        }
9748    }
9749
9750    public boolean testIsSystemReady() {
9751        // no need to synchronize(this) just to read & return the value
9752        return mSystemReady;
9753    }
9754
9755    private static File getCalledPreBootReceiversFile() {
9756        File dataDir = Environment.getDataDirectory();
9757        File systemDir = new File(dataDir, "system");
9758        File fname = new File(systemDir, "called_pre_boots.dat");
9759        return fname;
9760    }
9761
9762    static final int LAST_DONE_VERSION = 10000;
9763
9764    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9765        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9766        File file = getCalledPreBootReceiversFile();
9767        FileInputStream fis = null;
9768        try {
9769            fis = new FileInputStream(file);
9770            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9771            int fvers = dis.readInt();
9772            if (fvers == LAST_DONE_VERSION) {
9773                String vers = dis.readUTF();
9774                String codename = dis.readUTF();
9775                String build = dis.readUTF();
9776                if (android.os.Build.VERSION.RELEASE.equals(vers)
9777                        && android.os.Build.VERSION.CODENAME.equals(codename)
9778                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9779                    int num = dis.readInt();
9780                    while (num > 0) {
9781                        num--;
9782                        String pkg = dis.readUTF();
9783                        String cls = dis.readUTF();
9784                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9785                    }
9786                }
9787            }
9788        } catch (FileNotFoundException e) {
9789        } catch (IOException e) {
9790            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9791        } finally {
9792            if (fis != null) {
9793                try {
9794                    fis.close();
9795                } catch (IOException e) {
9796                }
9797            }
9798        }
9799        return lastDoneReceivers;
9800    }
9801
9802    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9803        File file = getCalledPreBootReceiversFile();
9804        FileOutputStream fos = null;
9805        DataOutputStream dos = null;
9806        try {
9807            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9808            fos = new FileOutputStream(file);
9809            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9810            dos.writeInt(LAST_DONE_VERSION);
9811            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9812            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9813            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9814            dos.writeInt(list.size());
9815            for (int i=0; i<list.size(); i++) {
9816                dos.writeUTF(list.get(i).getPackageName());
9817                dos.writeUTF(list.get(i).getClassName());
9818            }
9819        } catch (IOException e) {
9820            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9821            file.delete();
9822        } finally {
9823            FileUtils.sync(fos);
9824            if (dos != null) {
9825                try {
9826                    dos.close();
9827                } catch (IOException e) {
9828                    // TODO Auto-generated catch block
9829                    e.printStackTrace();
9830                }
9831            }
9832        }
9833    }
9834
9835    public void systemReady(final Runnable goingCallback) {
9836        synchronized(this) {
9837            if (mSystemReady) {
9838                if (goingCallback != null) goingCallback.run();
9839                return;
9840            }
9841
9842            if (mRecentTasks == null) {
9843                mRecentTasks = mTaskPersister.restoreTasksLocked();
9844                if (!mRecentTasks.isEmpty()) {
9845                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
9846                }
9847                mTaskPersister.startPersisting();
9848            }
9849
9850            // Check to see if there are any update receivers to run.
9851            if (!mDidUpdate) {
9852                if (mWaitingUpdate) {
9853                    return;
9854                }
9855                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9856                List<ResolveInfo> ris = null;
9857                try {
9858                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9859                            intent, null, 0, 0);
9860                } catch (RemoteException e) {
9861                }
9862                if (ris != null) {
9863                    for (int i=ris.size()-1; i>=0; i--) {
9864                        if ((ris.get(i).activityInfo.applicationInfo.flags
9865                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9866                            ris.remove(i);
9867                        }
9868                    }
9869                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9870
9871                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9872
9873                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9874                    for (int i=0; i<ris.size(); i++) {
9875                        ActivityInfo ai = ris.get(i).activityInfo;
9876                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9877                        if (lastDoneReceivers.contains(comp)) {
9878                            // We already did the pre boot receiver for this app with the current
9879                            // platform version, so don't do it again...
9880                            ris.remove(i);
9881                            i--;
9882                            // ...however, do keep it as one that has been done, so we don't
9883                            // forget about it when rewriting the file of last done receivers.
9884                            doneReceivers.add(comp);
9885                        }
9886                    }
9887
9888                    final int[] users = getUsersLocked();
9889                    for (int i=0; i<ris.size(); i++) {
9890                        ActivityInfo ai = ris.get(i).activityInfo;
9891                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9892                        doneReceivers.add(comp);
9893                        intent.setComponent(comp);
9894                        for (int j=0; j<users.length; j++) {
9895                            IIntentReceiver finisher = null;
9896                            if (i == ris.size()-1 && j == users.length-1) {
9897                                finisher = new IIntentReceiver.Stub() {
9898                                    public void performReceive(Intent intent, int resultCode,
9899                                            String data, Bundle extras, boolean ordered,
9900                                            boolean sticky, int sendingUser) {
9901                                        // The raw IIntentReceiver interface is called
9902                                        // with the AM lock held, so redispatch to
9903                                        // execute our code without the lock.
9904                                        mHandler.post(new Runnable() {
9905                                            public void run() {
9906                                                synchronized (ActivityManagerService.this) {
9907                                                    mDidUpdate = true;
9908                                                }
9909                                                writeLastDonePreBootReceivers(doneReceivers);
9910                                                showBootMessage(mContext.getText(
9911                                                        R.string.android_upgrading_complete),
9912                                                        false);
9913                                                systemReady(goingCallback);
9914                                            }
9915                                        });
9916                                    }
9917                                };
9918                            }
9919                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9920                                    + " for user " + users[j]);
9921                            broadcastIntentLocked(null, null, intent, null, finisher,
9922                                    0, null, null, null, AppOpsManager.OP_NONE,
9923                                    true, false, MY_PID, Process.SYSTEM_UID,
9924                                    users[j]);
9925                            if (finisher != null) {
9926                                mWaitingUpdate = true;
9927                            }
9928                        }
9929                    }
9930                }
9931                if (mWaitingUpdate) {
9932                    return;
9933                }
9934                mDidUpdate = true;
9935            }
9936
9937            mAppOpsService.systemReady();
9938            mUsageStatsService.systemReady();
9939            mSystemReady = true;
9940        }
9941
9942        ArrayList<ProcessRecord> procsToKill = null;
9943        synchronized(mPidsSelfLocked) {
9944            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9945                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9946                if (!isAllowedWhileBooting(proc.info)){
9947                    if (procsToKill == null) {
9948                        procsToKill = new ArrayList<ProcessRecord>();
9949                    }
9950                    procsToKill.add(proc);
9951                }
9952            }
9953        }
9954
9955        synchronized(this) {
9956            if (procsToKill != null) {
9957                for (int i=procsToKill.size()-1; i>=0; i--) {
9958                    ProcessRecord proc = procsToKill.get(i);
9959                    Slog.i(TAG, "Removing system update proc: " + proc);
9960                    removeProcessLocked(proc, true, false, "system update done");
9961                }
9962            }
9963
9964            // Now that we have cleaned up any update processes, we
9965            // are ready to start launching real processes and know that
9966            // we won't trample on them any more.
9967            mProcessesReady = true;
9968        }
9969
9970        Slog.i(TAG, "System now ready");
9971        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9972            SystemClock.uptimeMillis());
9973
9974        synchronized(this) {
9975            // Make sure we have no pre-ready processes sitting around.
9976
9977            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9978                ResolveInfo ri = mContext.getPackageManager()
9979                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9980                                STOCK_PM_FLAGS);
9981                CharSequence errorMsg = null;
9982                if (ri != null) {
9983                    ActivityInfo ai = ri.activityInfo;
9984                    ApplicationInfo app = ai.applicationInfo;
9985                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9986                        mTopAction = Intent.ACTION_FACTORY_TEST;
9987                        mTopData = null;
9988                        mTopComponent = new ComponentName(app.packageName,
9989                                ai.name);
9990                    } else {
9991                        errorMsg = mContext.getResources().getText(
9992                                com.android.internal.R.string.factorytest_not_system);
9993                    }
9994                } else {
9995                    errorMsg = mContext.getResources().getText(
9996                            com.android.internal.R.string.factorytest_no_action);
9997                }
9998                if (errorMsg != null) {
9999                    mTopAction = null;
10000                    mTopData = null;
10001                    mTopComponent = null;
10002                    Message msg = Message.obtain();
10003                    msg.what = SHOW_FACTORY_ERROR_MSG;
10004                    msg.getData().putCharSequence("msg", errorMsg);
10005                    mHandler.sendMessage(msg);
10006                }
10007            }
10008        }
10009
10010        retrieveSettings();
10011
10012        synchronized (this) {
10013            readGrantedUriPermissionsLocked();
10014        }
10015
10016        if (goingCallback != null) goingCallback.run();
10017
10018        mSystemServiceManager.startUser(mCurrentUserId);
10019
10020        synchronized (this) {
10021            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10022                try {
10023                    List apps = AppGlobals.getPackageManager().
10024                        getPersistentApplications(STOCK_PM_FLAGS);
10025                    if (apps != null) {
10026                        int N = apps.size();
10027                        int i;
10028                        for (i=0; i<N; i++) {
10029                            ApplicationInfo info
10030                                = (ApplicationInfo)apps.get(i);
10031                            if (info != null &&
10032                                    !info.packageName.equals("android")) {
10033                                addAppLocked(info, false, null /* ABI override */);
10034                            }
10035                        }
10036                    }
10037                } catch (RemoteException ex) {
10038                    // pm is in same process, this will never happen.
10039                }
10040            }
10041
10042            // Start up initial activity.
10043            mBooting = true;
10044
10045            try {
10046                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10047                    Message msg = Message.obtain();
10048                    msg.what = SHOW_UID_ERROR_MSG;
10049                    mHandler.sendMessage(msg);
10050                }
10051            } catch (RemoteException e) {
10052            }
10053
10054            long ident = Binder.clearCallingIdentity();
10055            try {
10056                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10057                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10058                        | Intent.FLAG_RECEIVER_FOREGROUND);
10059                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10060                broadcastIntentLocked(null, null, intent,
10061                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10062                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10063                intent = new Intent(Intent.ACTION_USER_STARTING);
10064                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10065                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10066                broadcastIntentLocked(null, null, intent,
10067                        null, new IIntentReceiver.Stub() {
10068                            @Override
10069                            public void performReceive(Intent intent, int resultCode, String data,
10070                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10071                                    throws RemoteException {
10072                            }
10073                        }, 0, null, null,
10074                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10075                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10076            } catch (Throwable t) {
10077                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10078            } finally {
10079                Binder.restoreCallingIdentity(ident);
10080            }
10081            mStackSupervisor.resumeTopActivitiesLocked();
10082            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10083        }
10084    }
10085
10086    private boolean makeAppCrashingLocked(ProcessRecord app,
10087            String shortMsg, String longMsg, String stackTrace) {
10088        app.crashing = true;
10089        app.crashingReport = generateProcessError(app,
10090                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10091        startAppProblemLocked(app);
10092        app.stopFreezingAllLocked();
10093        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10094    }
10095
10096    private void makeAppNotRespondingLocked(ProcessRecord app,
10097            String activity, String shortMsg, String longMsg) {
10098        app.notResponding = true;
10099        app.notRespondingReport = generateProcessError(app,
10100                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10101                activity, shortMsg, longMsg, null);
10102        startAppProblemLocked(app);
10103        app.stopFreezingAllLocked();
10104    }
10105
10106    /**
10107     * Generate a process error record, suitable for attachment to a ProcessRecord.
10108     *
10109     * @param app The ProcessRecord in which the error occurred.
10110     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10111     *                      ActivityManager.AppErrorStateInfo
10112     * @param activity The activity associated with the crash, if known.
10113     * @param shortMsg Short message describing the crash.
10114     * @param longMsg Long message describing the crash.
10115     * @param stackTrace Full crash stack trace, may be null.
10116     *
10117     * @return Returns a fully-formed AppErrorStateInfo record.
10118     */
10119    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10120            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10121        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10122
10123        report.condition = condition;
10124        report.processName = app.processName;
10125        report.pid = app.pid;
10126        report.uid = app.info.uid;
10127        report.tag = activity;
10128        report.shortMsg = shortMsg;
10129        report.longMsg = longMsg;
10130        report.stackTrace = stackTrace;
10131
10132        return report;
10133    }
10134
10135    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10136        synchronized (this) {
10137            app.crashing = false;
10138            app.crashingReport = null;
10139            app.notResponding = false;
10140            app.notRespondingReport = null;
10141            if (app.anrDialog == fromDialog) {
10142                app.anrDialog = null;
10143            }
10144            if (app.waitDialog == fromDialog) {
10145                app.waitDialog = null;
10146            }
10147            if (app.pid > 0 && app.pid != MY_PID) {
10148                handleAppCrashLocked(app, null, null, null);
10149                killUnneededProcessLocked(app, "user request after error");
10150            }
10151        }
10152    }
10153
10154    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10155            String stackTrace) {
10156        long now = SystemClock.uptimeMillis();
10157
10158        Long crashTime;
10159        if (!app.isolated) {
10160            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10161        } else {
10162            crashTime = null;
10163        }
10164        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10165            // This process loses!
10166            Slog.w(TAG, "Process " + app.info.processName
10167                    + " has crashed too many times: killing!");
10168            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10169                    app.userId, app.info.processName, app.uid);
10170            mStackSupervisor.handleAppCrashLocked(app);
10171            if (!app.persistent) {
10172                // We don't want to start this process again until the user
10173                // explicitly does so...  but for persistent process, we really
10174                // need to keep it running.  If a persistent process is actually
10175                // repeatedly crashing, then badness for everyone.
10176                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10177                        app.info.processName);
10178                if (!app.isolated) {
10179                    // XXX We don't have a way to mark isolated processes
10180                    // as bad, since they don't have a peristent identity.
10181                    mBadProcesses.put(app.info.processName, app.uid,
10182                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10183                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10184                }
10185                app.bad = true;
10186                app.removed = true;
10187                // Don't let services in this process be restarted and potentially
10188                // annoy the user repeatedly.  Unless it is persistent, since those
10189                // processes run critical code.
10190                removeProcessLocked(app, false, false, "crash");
10191                mStackSupervisor.resumeTopActivitiesLocked();
10192                return false;
10193            }
10194            mStackSupervisor.resumeTopActivitiesLocked();
10195        } else {
10196            mStackSupervisor.finishTopRunningActivityLocked(app);
10197        }
10198
10199        // Bump up the crash count of any services currently running in the proc.
10200        for (int i=app.services.size()-1; i>=0; i--) {
10201            // Any services running in the application need to be placed
10202            // back in the pending list.
10203            ServiceRecord sr = app.services.valueAt(i);
10204            sr.crashCount++;
10205        }
10206
10207        // If the crashing process is what we consider to be the "home process" and it has been
10208        // replaced by a third-party app, clear the package preferred activities from packages
10209        // with a home activity running in the process to prevent a repeatedly crashing app
10210        // from blocking the user to manually clear the list.
10211        final ArrayList<ActivityRecord> activities = app.activities;
10212        if (app == mHomeProcess && activities.size() > 0
10213                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10214            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10215                final ActivityRecord r = activities.get(activityNdx);
10216                if (r.isHomeActivity()) {
10217                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10218                    try {
10219                        ActivityThread.getPackageManager()
10220                                .clearPackagePreferredActivities(r.packageName);
10221                    } catch (RemoteException c) {
10222                        // pm is in same process, this will never happen.
10223                    }
10224                }
10225            }
10226        }
10227
10228        if (!app.isolated) {
10229            // XXX Can't keep track of crash times for isolated processes,
10230            // because they don't have a perisistent identity.
10231            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10232        }
10233
10234        return true;
10235    }
10236
10237    void startAppProblemLocked(ProcessRecord app) {
10238        if (app.userId == mCurrentUserId) {
10239            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10240                    mContext, app.info.packageName, app.info.flags);
10241        } else {
10242            // If this app is not running under the current user, then we
10243            // can't give it a report button because that would require
10244            // launching the report UI under a different user.
10245            app.errorReportReceiver = null;
10246        }
10247        skipCurrentReceiverLocked(app);
10248    }
10249
10250    void skipCurrentReceiverLocked(ProcessRecord app) {
10251        for (BroadcastQueue queue : mBroadcastQueues) {
10252            queue.skipCurrentReceiverLocked(app);
10253        }
10254    }
10255
10256    /**
10257     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10258     * The application process will exit immediately after this call returns.
10259     * @param app object of the crashing app, null for the system server
10260     * @param crashInfo describing the exception
10261     */
10262    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10263        ProcessRecord r = findAppProcess(app, "Crash");
10264        final String processName = app == null ? "system_server"
10265                : (r == null ? "unknown" : r.processName);
10266
10267        handleApplicationCrashInner("crash", r, processName, crashInfo);
10268    }
10269
10270    /* Native crash reporting uses this inner version because it needs to be somewhat
10271     * decoupled from the AM-managed cleanup lifecycle
10272     */
10273    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10274            ApplicationErrorReport.CrashInfo crashInfo) {
10275        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10276                UserHandle.getUserId(Binder.getCallingUid()), processName,
10277                r == null ? -1 : r.info.flags,
10278                crashInfo.exceptionClassName,
10279                crashInfo.exceptionMessage,
10280                crashInfo.throwFileName,
10281                crashInfo.throwLineNumber);
10282
10283        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10284
10285        crashApplication(r, crashInfo);
10286    }
10287
10288    public void handleApplicationStrictModeViolation(
10289            IBinder app,
10290            int violationMask,
10291            StrictMode.ViolationInfo info) {
10292        ProcessRecord r = findAppProcess(app, "StrictMode");
10293        if (r == null) {
10294            return;
10295        }
10296
10297        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10298            Integer stackFingerprint = info.hashCode();
10299            boolean logIt = true;
10300            synchronized (mAlreadyLoggedViolatedStacks) {
10301                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10302                    logIt = false;
10303                    // TODO: sub-sample into EventLog for these, with
10304                    // the info.durationMillis?  Then we'd get
10305                    // the relative pain numbers, without logging all
10306                    // the stack traces repeatedly.  We'd want to do
10307                    // likewise in the client code, which also does
10308                    // dup suppression, before the Binder call.
10309                } else {
10310                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10311                        mAlreadyLoggedViolatedStacks.clear();
10312                    }
10313                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10314                }
10315            }
10316            if (logIt) {
10317                logStrictModeViolationToDropBox(r, info);
10318            }
10319        }
10320
10321        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10322            AppErrorResult result = new AppErrorResult();
10323            synchronized (this) {
10324                final long origId = Binder.clearCallingIdentity();
10325
10326                Message msg = Message.obtain();
10327                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10328                HashMap<String, Object> data = new HashMap<String, Object>();
10329                data.put("result", result);
10330                data.put("app", r);
10331                data.put("violationMask", violationMask);
10332                data.put("info", info);
10333                msg.obj = data;
10334                mHandler.sendMessage(msg);
10335
10336                Binder.restoreCallingIdentity(origId);
10337            }
10338            int res = result.get();
10339            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10340        }
10341    }
10342
10343    // Depending on the policy in effect, there could be a bunch of
10344    // these in quick succession so we try to batch these together to
10345    // minimize disk writes, number of dropbox entries, and maximize
10346    // compression, by having more fewer, larger records.
10347    private void logStrictModeViolationToDropBox(
10348            ProcessRecord process,
10349            StrictMode.ViolationInfo info) {
10350        if (info == null) {
10351            return;
10352        }
10353        final boolean isSystemApp = process == null ||
10354                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10355                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10356        final String processName = process == null ? "unknown" : process.processName;
10357        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10358        final DropBoxManager dbox = (DropBoxManager)
10359                mContext.getSystemService(Context.DROPBOX_SERVICE);
10360
10361        // Exit early if the dropbox isn't configured to accept this report type.
10362        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10363
10364        boolean bufferWasEmpty;
10365        boolean needsFlush;
10366        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10367        synchronized (sb) {
10368            bufferWasEmpty = sb.length() == 0;
10369            appendDropBoxProcessHeaders(process, processName, sb);
10370            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10371            sb.append("System-App: ").append(isSystemApp).append("\n");
10372            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10373            if (info.violationNumThisLoop != 0) {
10374                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10375            }
10376            if (info.numAnimationsRunning != 0) {
10377                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10378            }
10379            if (info.broadcastIntentAction != null) {
10380                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10381            }
10382            if (info.durationMillis != -1) {
10383                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10384            }
10385            if (info.numInstances != -1) {
10386                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10387            }
10388            if (info.tags != null) {
10389                for (String tag : info.tags) {
10390                    sb.append("Span-Tag: ").append(tag).append("\n");
10391                }
10392            }
10393            sb.append("\n");
10394            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10395                sb.append(info.crashInfo.stackTrace);
10396            }
10397            sb.append("\n");
10398
10399            // Only buffer up to ~64k.  Various logging bits truncate
10400            // things at 128k.
10401            needsFlush = (sb.length() > 64 * 1024);
10402        }
10403
10404        // Flush immediately if the buffer's grown too large, or this
10405        // is a non-system app.  Non-system apps are isolated with a
10406        // different tag & policy and not batched.
10407        //
10408        // Batching is useful during internal testing with
10409        // StrictMode settings turned up high.  Without batching,
10410        // thousands of separate files could be created on boot.
10411        if (!isSystemApp || needsFlush) {
10412            new Thread("Error dump: " + dropboxTag) {
10413                @Override
10414                public void run() {
10415                    String report;
10416                    synchronized (sb) {
10417                        report = sb.toString();
10418                        sb.delete(0, sb.length());
10419                        sb.trimToSize();
10420                    }
10421                    if (report.length() != 0) {
10422                        dbox.addText(dropboxTag, report);
10423                    }
10424                }
10425            }.start();
10426            return;
10427        }
10428
10429        // System app batching:
10430        if (!bufferWasEmpty) {
10431            // An existing dropbox-writing thread is outstanding, so
10432            // we don't need to start it up.  The existing thread will
10433            // catch the buffer appends we just did.
10434            return;
10435        }
10436
10437        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10438        // (After this point, we shouldn't access AMS internal data structures.)
10439        new Thread("Error dump: " + dropboxTag) {
10440            @Override
10441            public void run() {
10442                // 5 second sleep to let stacks arrive and be batched together
10443                try {
10444                    Thread.sleep(5000);  // 5 seconds
10445                } catch (InterruptedException e) {}
10446
10447                String errorReport;
10448                synchronized (mStrictModeBuffer) {
10449                    errorReport = mStrictModeBuffer.toString();
10450                    if (errorReport.length() == 0) {
10451                        return;
10452                    }
10453                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10454                    mStrictModeBuffer.trimToSize();
10455                }
10456                dbox.addText(dropboxTag, errorReport);
10457            }
10458        }.start();
10459    }
10460
10461    /**
10462     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10463     * @param app object of the crashing app, null for the system server
10464     * @param tag reported by the caller
10465     * @param crashInfo describing the context of the error
10466     * @return true if the process should exit immediately (WTF is fatal)
10467     */
10468    public boolean handleApplicationWtf(IBinder app, String tag,
10469            ApplicationErrorReport.CrashInfo crashInfo) {
10470        ProcessRecord r = findAppProcess(app, "WTF");
10471        final String processName = app == null ? "system_server"
10472                : (r == null ? "unknown" : r.processName);
10473
10474        EventLog.writeEvent(EventLogTags.AM_WTF,
10475                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10476                processName,
10477                r == null ? -1 : r.info.flags,
10478                tag, crashInfo.exceptionMessage);
10479
10480        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10481
10482        if (r != null && r.pid != Process.myPid() &&
10483                Settings.Global.getInt(mContext.getContentResolver(),
10484                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10485            crashApplication(r, crashInfo);
10486            return true;
10487        } else {
10488            return false;
10489        }
10490    }
10491
10492    /**
10493     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10494     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10495     */
10496    private ProcessRecord findAppProcess(IBinder app, String reason) {
10497        if (app == null) {
10498            return null;
10499        }
10500
10501        synchronized (this) {
10502            final int NP = mProcessNames.getMap().size();
10503            for (int ip=0; ip<NP; ip++) {
10504                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10505                final int NA = apps.size();
10506                for (int ia=0; ia<NA; ia++) {
10507                    ProcessRecord p = apps.valueAt(ia);
10508                    if (p.thread != null && p.thread.asBinder() == app) {
10509                        return p;
10510                    }
10511                }
10512            }
10513
10514            Slog.w(TAG, "Can't find mystery application for " + reason
10515                    + " from pid=" + Binder.getCallingPid()
10516                    + " uid=" + Binder.getCallingUid() + ": " + app);
10517            return null;
10518        }
10519    }
10520
10521    /**
10522     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10523     * to append various headers to the dropbox log text.
10524     */
10525    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10526            StringBuilder sb) {
10527        // Watchdog thread ends up invoking this function (with
10528        // a null ProcessRecord) to add the stack file to dropbox.
10529        // Do not acquire a lock on this (am) in such cases, as it
10530        // could cause a potential deadlock, if and when watchdog
10531        // is invoked due to unavailability of lock on am and it
10532        // would prevent watchdog from killing system_server.
10533        if (process == null) {
10534            sb.append("Process: ").append(processName).append("\n");
10535            return;
10536        }
10537        // Note: ProcessRecord 'process' is guarded by the service
10538        // instance.  (notably process.pkgList, which could otherwise change
10539        // concurrently during execution of this method)
10540        synchronized (this) {
10541            sb.append("Process: ").append(processName).append("\n");
10542            int flags = process.info.flags;
10543            IPackageManager pm = AppGlobals.getPackageManager();
10544            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10545            for (int ip=0; ip<process.pkgList.size(); ip++) {
10546                String pkg = process.pkgList.keyAt(ip);
10547                sb.append("Package: ").append(pkg);
10548                try {
10549                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10550                    if (pi != null) {
10551                        sb.append(" v").append(pi.versionCode);
10552                        if (pi.versionName != null) {
10553                            sb.append(" (").append(pi.versionName).append(")");
10554                        }
10555                    }
10556                } catch (RemoteException e) {
10557                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10558                }
10559                sb.append("\n");
10560            }
10561        }
10562    }
10563
10564    private static String processClass(ProcessRecord process) {
10565        if (process == null || process.pid == MY_PID) {
10566            return "system_server";
10567        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10568            return "system_app";
10569        } else {
10570            return "data_app";
10571        }
10572    }
10573
10574    /**
10575     * Write a description of an error (crash, WTF, ANR) to the drop box.
10576     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10577     * @param process which caused the error, null means the system server
10578     * @param activity which triggered the error, null if unknown
10579     * @param parent activity related to the error, null if unknown
10580     * @param subject line related to the error, null if absent
10581     * @param report in long form describing the error, null if absent
10582     * @param logFile to include in the report, null if none
10583     * @param crashInfo giving an application stack trace, null if absent
10584     */
10585    public void addErrorToDropBox(String eventType,
10586            ProcessRecord process, String processName, ActivityRecord activity,
10587            ActivityRecord parent, String subject,
10588            final String report, final File logFile,
10589            final ApplicationErrorReport.CrashInfo crashInfo) {
10590        // NOTE -- this must never acquire the ActivityManagerService lock,
10591        // otherwise the watchdog may be prevented from resetting the system.
10592
10593        final String dropboxTag = processClass(process) + "_" + eventType;
10594        final DropBoxManager dbox = (DropBoxManager)
10595                mContext.getSystemService(Context.DROPBOX_SERVICE);
10596
10597        // Exit early if the dropbox isn't configured to accept this report type.
10598        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10599
10600        final StringBuilder sb = new StringBuilder(1024);
10601        appendDropBoxProcessHeaders(process, processName, sb);
10602        if (activity != null) {
10603            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10604        }
10605        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10606            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10607        }
10608        if (parent != null && parent != activity) {
10609            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10610        }
10611        if (subject != null) {
10612            sb.append("Subject: ").append(subject).append("\n");
10613        }
10614        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10615        if (Debug.isDebuggerConnected()) {
10616            sb.append("Debugger: Connected\n");
10617        }
10618        sb.append("\n");
10619
10620        // Do the rest in a worker thread to avoid blocking the caller on I/O
10621        // (After this point, we shouldn't access AMS internal data structures.)
10622        Thread worker = new Thread("Error dump: " + dropboxTag) {
10623            @Override
10624            public void run() {
10625                if (report != null) {
10626                    sb.append(report);
10627                }
10628                if (logFile != null) {
10629                    try {
10630                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10631                                    "\n\n[[TRUNCATED]]"));
10632                    } catch (IOException e) {
10633                        Slog.e(TAG, "Error reading " + logFile, e);
10634                    }
10635                }
10636                if (crashInfo != null && crashInfo.stackTrace != null) {
10637                    sb.append(crashInfo.stackTrace);
10638                }
10639
10640                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10641                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10642                if (lines > 0) {
10643                    sb.append("\n");
10644
10645                    // Merge several logcat streams, and take the last N lines
10646                    InputStreamReader input = null;
10647                    try {
10648                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10649                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10650                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10651
10652                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10653                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10654                        input = new InputStreamReader(logcat.getInputStream());
10655
10656                        int num;
10657                        char[] buf = new char[8192];
10658                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10659                    } catch (IOException e) {
10660                        Slog.e(TAG, "Error running logcat", e);
10661                    } finally {
10662                        if (input != null) try { input.close(); } catch (IOException e) {}
10663                    }
10664                }
10665
10666                dbox.addText(dropboxTag, sb.toString());
10667            }
10668        };
10669
10670        if (process == null) {
10671            // If process is null, we are being called from some internal code
10672            // and may be about to die -- run this synchronously.
10673            worker.run();
10674        } else {
10675            worker.start();
10676        }
10677    }
10678
10679    /**
10680     * Bring up the "unexpected error" dialog box for a crashing app.
10681     * Deal with edge cases (intercepts from instrumented applications,
10682     * ActivityController, error intent receivers, that sort of thing).
10683     * @param r the application crashing
10684     * @param crashInfo describing the failure
10685     */
10686    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10687        long timeMillis = System.currentTimeMillis();
10688        String shortMsg = crashInfo.exceptionClassName;
10689        String longMsg = crashInfo.exceptionMessage;
10690        String stackTrace = crashInfo.stackTrace;
10691        if (shortMsg != null && longMsg != null) {
10692            longMsg = shortMsg + ": " + longMsg;
10693        } else if (shortMsg != null) {
10694            longMsg = shortMsg;
10695        }
10696
10697        AppErrorResult result = new AppErrorResult();
10698        synchronized (this) {
10699            if (mController != null) {
10700                try {
10701                    String name = r != null ? r.processName : null;
10702                    int pid = r != null ? r.pid : Binder.getCallingPid();
10703                    if (!mController.appCrashed(name, pid,
10704                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10705                        Slog.w(TAG, "Force-killing crashed app " + name
10706                                + " at watcher's request");
10707                        Process.killProcess(pid);
10708                        return;
10709                    }
10710                } catch (RemoteException e) {
10711                    mController = null;
10712                    Watchdog.getInstance().setActivityController(null);
10713                }
10714            }
10715
10716            final long origId = Binder.clearCallingIdentity();
10717
10718            // If this process is running instrumentation, finish it.
10719            if (r != null && r.instrumentationClass != null) {
10720                Slog.w(TAG, "Error in app " + r.processName
10721                      + " running instrumentation " + r.instrumentationClass + ":");
10722                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10723                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10724                Bundle info = new Bundle();
10725                info.putString("shortMsg", shortMsg);
10726                info.putString("longMsg", longMsg);
10727                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10728                Binder.restoreCallingIdentity(origId);
10729                return;
10730            }
10731
10732            // If we can't identify the process or it's already exceeded its crash quota,
10733            // quit right away without showing a crash dialog.
10734            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10735                Binder.restoreCallingIdentity(origId);
10736                return;
10737            }
10738
10739            Message msg = Message.obtain();
10740            msg.what = SHOW_ERROR_MSG;
10741            HashMap data = new HashMap();
10742            data.put("result", result);
10743            data.put("app", r);
10744            msg.obj = data;
10745            mHandler.sendMessage(msg);
10746
10747            Binder.restoreCallingIdentity(origId);
10748        }
10749
10750        int res = result.get();
10751
10752        Intent appErrorIntent = null;
10753        synchronized (this) {
10754            if (r != null && !r.isolated) {
10755                // XXX Can't keep track of crash time for isolated processes,
10756                // since they don't have a persistent identity.
10757                mProcessCrashTimes.put(r.info.processName, r.uid,
10758                        SystemClock.uptimeMillis());
10759            }
10760            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10761                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10762            }
10763        }
10764
10765        if (appErrorIntent != null) {
10766            try {
10767                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10768            } catch (ActivityNotFoundException e) {
10769                Slog.w(TAG, "bug report receiver dissappeared", e);
10770            }
10771        }
10772    }
10773
10774    Intent createAppErrorIntentLocked(ProcessRecord r,
10775            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10776        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10777        if (report == null) {
10778            return null;
10779        }
10780        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10781        result.setComponent(r.errorReportReceiver);
10782        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10783        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10784        return result;
10785    }
10786
10787    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10788            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10789        if (r.errorReportReceiver == null) {
10790            return null;
10791        }
10792
10793        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10794            return null;
10795        }
10796
10797        ApplicationErrorReport report = new ApplicationErrorReport();
10798        report.packageName = r.info.packageName;
10799        report.installerPackageName = r.errorReportReceiver.getPackageName();
10800        report.processName = r.processName;
10801        report.time = timeMillis;
10802        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10803
10804        if (r.crashing || r.forceCrashReport) {
10805            report.type = ApplicationErrorReport.TYPE_CRASH;
10806            report.crashInfo = crashInfo;
10807        } else if (r.notResponding) {
10808            report.type = ApplicationErrorReport.TYPE_ANR;
10809            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10810
10811            report.anrInfo.activity = r.notRespondingReport.tag;
10812            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10813            report.anrInfo.info = r.notRespondingReport.longMsg;
10814        }
10815
10816        return report;
10817    }
10818
10819    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10820        enforceNotIsolatedCaller("getProcessesInErrorState");
10821        // assume our apps are happy - lazy create the list
10822        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10823
10824        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10825                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10826        int userId = UserHandle.getUserId(Binder.getCallingUid());
10827
10828        synchronized (this) {
10829
10830            // iterate across all processes
10831            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10832                ProcessRecord app = mLruProcesses.get(i);
10833                if (!allUsers && app.userId != userId) {
10834                    continue;
10835                }
10836                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10837                    // This one's in trouble, so we'll generate a report for it
10838                    // crashes are higher priority (in case there's a crash *and* an anr)
10839                    ActivityManager.ProcessErrorStateInfo report = null;
10840                    if (app.crashing) {
10841                        report = app.crashingReport;
10842                    } else if (app.notResponding) {
10843                        report = app.notRespondingReport;
10844                    }
10845
10846                    if (report != null) {
10847                        if (errList == null) {
10848                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10849                        }
10850                        errList.add(report);
10851                    } else {
10852                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10853                                " crashing = " + app.crashing +
10854                                " notResponding = " + app.notResponding);
10855                    }
10856                }
10857            }
10858        }
10859
10860        return errList;
10861    }
10862
10863    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10864        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10865            if (currApp != null) {
10866                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10867            }
10868            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10869        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10870            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10871        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10872            if (currApp != null) {
10873                currApp.lru = 0;
10874            }
10875            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10876        } else if (adj >= ProcessList.SERVICE_ADJ) {
10877            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10878        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10879            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10880        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10881            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10882        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10883            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10884        } else {
10885            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10886        }
10887    }
10888
10889    private void fillInProcMemInfo(ProcessRecord app,
10890            ActivityManager.RunningAppProcessInfo outInfo) {
10891        outInfo.pid = app.pid;
10892        outInfo.uid = app.info.uid;
10893        if (mHeavyWeightProcess == app) {
10894            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10895        }
10896        if (app.persistent) {
10897            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10898        }
10899        if (app.activities.size() > 0) {
10900            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10901        }
10902        outInfo.lastTrimLevel = app.trimMemoryLevel;
10903        int adj = app.curAdj;
10904        outInfo.importance = oomAdjToImportance(adj, outInfo);
10905        outInfo.importanceReasonCode = app.adjTypeCode;
10906        outInfo.processState = app.curProcState;
10907    }
10908
10909    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10910        enforceNotIsolatedCaller("getRunningAppProcesses");
10911        // Lazy instantiation of list
10912        List<ActivityManager.RunningAppProcessInfo> runList = null;
10913        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10914                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10915        int userId = UserHandle.getUserId(Binder.getCallingUid());
10916        synchronized (this) {
10917            // Iterate across all processes
10918            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10919                ProcessRecord app = mLruProcesses.get(i);
10920                if (!allUsers && app.userId != userId) {
10921                    continue;
10922                }
10923                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10924                    // Generate process state info for running application
10925                    ActivityManager.RunningAppProcessInfo currApp =
10926                        new ActivityManager.RunningAppProcessInfo(app.processName,
10927                                app.pid, app.getPackageList());
10928                    fillInProcMemInfo(app, currApp);
10929                    if (app.adjSource instanceof ProcessRecord) {
10930                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10931                        currApp.importanceReasonImportance = oomAdjToImportance(
10932                                app.adjSourceOom, null);
10933                    } else if (app.adjSource instanceof ActivityRecord) {
10934                        ActivityRecord r = (ActivityRecord)app.adjSource;
10935                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10936                    }
10937                    if (app.adjTarget instanceof ComponentName) {
10938                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10939                    }
10940                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10941                    //        + " lru=" + currApp.lru);
10942                    if (runList == null) {
10943                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10944                    }
10945                    runList.add(currApp);
10946                }
10947            }
10948        }
10949        return runList;
10950    }
10951
10952    public List<ApplicationInfo> getRunningExternalApplications() {
10953        enforceNotIsolatedCaller("getRunningExternalApplications");
10954        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10955        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10956        if (runningApps != null && runningApps.size() > 0) {
10957            Set<String> extList = new HashSet<String>();
10958            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10959                if (app.pkgList != null) {
10960                    for (String pkg : app.pkgList) {
10961                        extList.add(pkg);
10962                    }
10963                }
10964            }
10965            IPackageManager pm = AppGlobals.getPackageManager();
10966            for (String pkg : extList) {
10967                try {
10968                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10969                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10970                        retList.add(info);
10971                    }
10972                } catch (RemoteException e) {
10973                }
10974            }
10975        }
10976        return retList;
10977    }
10978
10979    @Override
10980    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10981        enforceNotIsolatedCaller("getMyMemoryState");
10982        synchronized (this) {
10983            ProcessRecord proc;
10984            synchronized (mPidsSelfLocked) {
10985                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10986            }
10987            fillInProcMemInfo(proc, outInfo);
10988        }
10989    }
10990
10991    @Override
10992    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10993        if (checkCallingPermission(android.Manifest.permission.DUMP)
10994                != PackageManager.PERMISSION_GRANTED) {
10995            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10996                    + Binder.getCallingPid()
10997                    + ", uid=" + Binder.getCallingUid()
10998                    + " without permission "
10999                    + android.Manifest.permission.DUMP);
11000            return;
11001        }
11002
11003        boolean dumpAll = false;
11004        boolean dumpClient = false;
11005        String dumpPackage = null;
11006
11007        int opti = 0;
11008        while (opti < args.length) {
11009            String opt = args[opti];
11010            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11011                break;
11012            }
11013            opti++;
11014            if ("-a".equals(opt)) {
11015                dumpAll = true;
11016            } else if ("-c".equals(opt)) {
11017                dumpClient = true;
11018            } else if ("-h".equals(opt)) {
11019                pw.println("Activity manager dump options:");
11020                pw.println("  [-a] [-c] [-h] [cmd] ...");
11021                pw.println("  cmd may be one of:");
11022                pw.println("    a[ctivities]: activity stack state");
11023                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11024                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11025                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11026                pw.println("    o[om]: out of memory management");
11027                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11028                pw.println("    provider [COMP_SPEC]: provider client-side state");
11029                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11030                pw.println("    service [COMP_SPEC]: service client-side state");
11031                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11032                pw.println("    all: dump all activities");
11033                pw.println("    top: dump the top activity");
11034                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11035                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11036                pw.println("    a partial substring in a component name, a");
11037                pw.println("    hex object identifier.");
11038                pw.println("  -a: include all available server state.");
11039                pw.println("  -c: include client state.");
11040                return;
11041            } else {
11042                pw.println("Unknown argument: " + opt + "; use -h for help");
11043            }
11044        }
11045
11046        long origId = Binder.clearCallingIdentity();
11047        boolean more = false;
11048        // Is the caller requesting to dump a particular piece of data?
11049        if (opti < args.length) {
11050            String cmd = args[opti];
11051            opti++;
11052            if ("activities".equals(cmd) || "a".equals(cmd)) {
11053                synchronized (this) {
11054                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11055                }
11056            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11057                String[] newArgs;
11058                String name;
11059                if (opti >= args.length) {
11060                    name = null;
11061                    newArgs = EMPTY_STRING_ARRAY;
11062                } else {
11063                    name = args[opti];
11064                    opti++;
11065                    newArgs = new String[args.length - opti];
11066                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11067                            args.length - opti);
11068                }
11069                synchronized (this) {
11070                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11071                }
11072            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11073                String[] newArgs;
11074                String name;
11075                if (opti >= args.length) {
11076                    name = null;
11077                    newArgs = EMPTY_STRING_ARRAY;
11078                } else {
11079                    name = args[opti];
11080                    opti++;
11081                    newArgs = new String[args.length - opti];
11082                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11083                            args.length - opti);
11084                }
11085                synchronized (this) {
11086                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11087                }
11088            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11089                String[] newArgs;
11090                String name;
11091                if (opti >= args.length) {
11092                    name = null;
11093                    newArgs = EMPTY_STRING_ARRAY;
11094                } else {
11095                    name = args[opti];
11096                    opti++;
11097                    newArgs = new String[args.length - opti];
11098                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11099                            args.length - opti);
11100                }
11101                synchronized (this) {
11102                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11103                }
11104            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11105                synchronized (this) {
11106                    dumpOomLocked(fd, pw, args, opti, true);
11107                }
11108            } else if ("provider".equals(cmd)) {
11109                String[] newArgs;
11110                String name;
11111                if (opti >= args.length) {
11112                    name = null;
11113                    newArgs = EMPTY_STRING_ARRAY;
11114                } else {
11115                    name = args[opti];
11116                    opti++;
11117                    newArgs = new String[args.length - opti];
11118                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11119                }
11120                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11121                    pw.println("No providers match: " + name);
11122                    pw.println("Use -h for help.");
11123                }
11124            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11125                synchronized (this) {
11126                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11127                }
11128            } else if ("service".equals(cmd)) {
11129                String[] newArgs;
11130                String name;
11131                if (opti >= args.length) {
11132                    name = null;
11133                    newArgs = EMPTY_STRING_ARRAY;
11134                } else {
11135                    name = args[opti];
11136                    opti++;
11137                    newArgs = new String[args.length - opti];
11138                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11139                            args.length - opti);
11140                }
11141                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11142                    pw.println("No services match: " + name);
11143                    pw.println("Use -h for help.");
11144                }
11145            } else if ("package".equals(cmd)) {
11146                String[] newArgs;
11147                if (opti >= args.length) {
11148                    pw.println("package: no package name specified");
11149                    pw.println("Use -h for help.");
11150                } else {
11151                    dumpPackage = args[opti];
11152                    opti++;
11153                    newArgs = new String[args.length - opti];
11154                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11155                            args.length - opti);
11156                    args = newArgs;
11157                    opti = 0;
11158                    more = true;
11159                }
11160            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11161                synchronized (this) {
11162                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11163                }
11164            } else {
11165                // Dumping a single activity?
11166                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11167                    pw.println("Bad activity command, or no activities match: " + cmd);
11168                    pw.println("Use -h for help.");
11169                }
11170            }
11171            if (!more) {
11172                Binder.restoreCallingIdentity(origId);
11173                return;
11174            }
11175        }
11176
11177        // No piece of data specified, dump everything.
11178        synchronized (this) {
11179            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11180            pw.println();
11181            if (dumpAll) {
11182                pw.println("-------------------------------------------------------------------------------");
11183            }
11184            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11185            pw.println();
11186            if (dumpAll) {
11187                pw.println("-------------------------------------------------------------------------------");
11188            }
11189            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11190            pw.println();
11191            if (dumpAll) {
11192                pw.println("-------------------------------------------------------------------------------");
11193            }
11194            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11195            pw.println();
11196            if (dumpAll) {
11197                pw.println("-------------------------------------------------------------------------------");
11198            }
11199            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11200            pw.println();
11201            if (dumpAll) {
11202                pw.println("-------------------------------------------------------------------------------");
11203            }
11204            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11205        }
11206        Binder.restoreCallingIdentity(origId);
11207    }
11208
11209    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11210            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11211        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11212
11213        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11214                dumpPackage);
11215        boolean needSep = printedAnything;
11216
11217        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11218                dumpPackage, needSep, "  mFocusedActivity: ");
11219        if (printed) {
11220            printedAnything = true;
11221            needSep = false;
11222        }
11223
11224        if (dumpPackage == null) {
11225            if (needSep) {
11226                pw.println();
11227            }
11228            needSep = true;
11229            printedAnything = true;
11230            mStackSupervisor.dump(pw, "  ");
11231        }
11232
11233        if (mRecentTasks.size() > 0) {
11234            boolean printedHeader = false;
11235
11236            final int N = mRecentTasks.size();
11237            for (int i=0; i<N; i++) {
11238                TaskRecord tr = mRecentTasks.get(i);
11239                if (dumpPackage != null) {
11240                    if (tr.realActivity == null ||
11241                            !dumpPackage.equals(tr.realActivity)) {
11242                        continue;
11243                    }
11244                }
11245                if (!printedHeader) {
11246                    if (needSep) {
11247                        pw.println();
11248                    }
11249                    pw.println("  Recent tasks:");
11250                    printedHeader = true;
11251                    printedAnything = true;
11252                }
11253                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11254                        pw.println(tr);
11255                if (dumpAll) {
11256                    mRecentTasks.get(i).dump(pw, "    ");
11257                }
11258            }
11259        }
11260
11261        if (!printedAnything) {
11262            pw.println("  (nothing)");
11263        }
11264    }
11265
11266    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11267            int opti, boolean dumpAll, String dumpPackage) {
11268        boolean needSep = false;
11269        boolean printedAnything = false;
11270        int numPers = 0;
11271
11272        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11273
11274        if (dumpAll) {
11275            final int NP = mProcessNames.getMap().size();
11276            for (int ip=0; ip<NP; ip++) {
11277                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11278                final int NA = procs.size();
11279                for (int ia=0; ia<NA; ia++) {
11280                    ProcessRecord r = procs.valueAt(ia);
11281                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11282                        continue;
11283                    }
11284                    if (!needSep) {
11285                        pw.println("  All known processes:");
11286                        needSep = true;
11287                        printedAnything = true;
11288                    }
11289                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11290                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11291                        pw.print(" "); pw.println(r);
11292                    r.dump(pw, "    ");
11293                    if (r.persistent) {
11294                        numPers++;
11295                    }
11296                }
11297            }
11298        }
11299
11300        if (mIsolatedProcesses.size() > 0) {
11301            boolean printed = false;
11302            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11303                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11304                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11305                    continue;
11306                }
11307                if (!printed) {
11308                    if (needSep) {
11309                        pw.println();
11310                    }
11311                    pw.println("  Isolated process list (sorted by uid):");
11312                    printedAnything = true;
11313                    printed = true;
11314                    needSep = true;
11315                }
11316                pw.println(String.format("%sIsolated #%2d: %s",
11317                        "    ", i, r.toString()));
11318            }
11319        }
11320
11321        if (mLruProcesses.size() > 0) {
11322            if (needSep) {
11323                pw.println();
11324            }
11325            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11326                    pw.print(" total, non-act at ");
11327                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11328                    pw.print(", non-svc at ");
11329                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11330                    pw.println("):");
11331            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11332            needSep = true;
11333            printedAnything = true;
11334        }
11335
11336        if (dumpAll || dumpPackage != null) {
11337            synchronized (mPidsSelfLocked) {
11338                boolean printed = false;
11339                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11340                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11341                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11342                        continue;
11343                    }
11344                    if (!printed) {
11345                        if (needSep) pw.println();
11346                        needSep = true;
11347                        pw.println("  PID mappings:");
11348                        printed = true;
11349                        printedAnything = true;
11350                    }
11351                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11352                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11353                }
11354            }
11355        }
11356
11357        if (mForegroundProcesses.size() > 0) {
11358            synchronized (mPidsSelfLocked) {
11359                boolean printed = false;
11360                for (int i=0; i<mForegroundProcesses.size(); i++) {
11361                    ProcessRecord r = mPidsSelfLocked.get(
11362                            mForegroundProcesses.valueAt(i).pid);
11363                    if (dumpPackage != null && (r == null
11364                            || !r.pkgList.containsKey(dumpPackage))) {
11365                        continue;
11366                    }
11367                    if (!printed) {
11368                        if (needSep) pw.println();
11369                        needSep = true;
11370                        pw.println("  Foreground Processes:");
11371                        printed = true;
11372                        printedAnything = true;
11373                    }
11374                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11375                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11376                }
11377            }
11378        }
11379
11380        if (mPersistentStartingProcesses.size() > 0) {
11381            if (needSep) pw.println();
11382            needSep = true;
11383            printedAnything = true;
11384            pw.println("  Persisent processes that are starting:");
11385            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11386                    "Starting Norm", "Restarting PERS", dumpPackage);
11387        }
11388
11389        if (mRemovedProcesses.size() > 0) {
11390            if (needSep) pw.println();
11391            needSep = true;
11392            printedAnything = true;
11393            pw.println("  Processes that are being removed:");
11394            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11395                    "Removed Norm", "Removed PERS", dumpPackage);
11396        }
11397
11398        if (mProcessesOnHold.size() > 0) {
11399            if (needSep) pw.println();
11400            needSep = true;
11401            printedAnything = true;
11402            pw.println("  Processes that are on old until the system is ready:");
11403            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11404                    "OnHold Norm", "OnHold PERS", dumpPackage);
11405        }
11406
11407        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11408
11409        if (mProcessCrashTimes.getMap().size() > 0) {
11410            boolean printed = false;
11411            long now = SystemClock.uptimeMillis();
11412            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11413            final int NP = pmap.size();
11414            for (int ip=0; ip<NP; ip++) {
11415                String pname = pmap.keyAt(ip);
11416                SparseArray<Long> 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("  Time since processes crashed:");
11429                        printed = true;
11430                        printedAnything = true;
11431                    }
11432                    pw.print("    Process "); pw.print(pname);
11433                            pw.print(" uid "); pw.print(puid);
11434                            pw.print(": last crashed ");
11435                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11436                            pw.println(" ago");
11437                }
11438            }
11439        }
11440
11441        if (mBadProcesses.getMap().size() > 0) {
11442            boolean printed = false;
11443            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11444            final int NP = pmap.size();
11445            for (int ip=0; ip<NP; ip++) {
11446                String pname = pmap.keyAt(ip);
11447                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11448                final int N = uids.size();
11449                for (int i=0; i<N; i++) {
11450                    int puid = uids.keyAt(i);
11451                    ProcessRecord r = mProcessNames.get(pname, puid);
11452                    if (dumpPackage != null && (r == null
11453                            || !r.pkgList.containsKey(dumpPackage))) {
11454                        continue;
11455                    }
11456                    if (!printed) {
11457                        if (needSep) pw.println();
11458                        needSep = true;
11459                        pw.println("  Bad processes:");
11460                        printedAnything = true;
11461                    }
11462                    BadProcessInfo info = uids.valueAt(i);
11463                    pw.print("    Bad process "); pw.print(pname);
11464                            pw.print(" uid "); pw.print(puid);
11465                            pw.print(": crashed at time "); pw.println(info.time);
11466                    if (info.shortMsg != null) {
11467                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11468                    }
11469                    if (info.longMsg != null) {
11470                        pw.print("      Long msg: "); pw.println(info.longMsg);
11471                    }
11472                    if (info.stack != null) {
11473                        pw.println("      Stack:");
11474                        int lastPos = 0;
11475                        for (int pos=0; pos<info.stack.length(); pos++) {
11476                            if (info.stack.charAt(pos) == '\n') {
11477                                pw.print("        ");
11478                                pw.write(info.stack, lastPos, pos-lastPos);
11479                                pw.println();
11480                                lastPos = pos+1;
11481                            }
11482                        }
11483                        if (lastPos < info.stack.length()) {
11484                            pw.print("        ");
11485                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11486                            pw.println();
11487                        }
11488                    }
11489                }
11490            }
11491        }
11492
11493        if (dumpPackage == null) {
11494            pw.println();
11495            needSep = false;
11496            pw.println("  mStartedUsers:");
11497            for (int i=0; i<mStartedUsers.size(); i++) {
11498                UserStartedState uss = mStartedUsers.valueAt(i);
11499                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11500                        pw.print(": "); uss.dump("", pw);
11501            }
11502            pw.print("  mStartedUserArray: [");
11503            for (int i=0; i<mStartedUserArray.length; i++) {
11504                if (i > 0) pw.print(", ");
11505                pw.print(mStartedUserArray[i]);
11506            }
11507            pw.println("]");
11508            pw.print("  mUserLru: [");
11509            for (int i=0; i<mUserLru.size(); i++) {
11510                if (i > 0) pw.print(", ");
11511                pw.print(mUserLru.get(i));
11512            }
11513            pw.println("]");
11514            if (dumpAll) {
11515                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11516            }
11517        }
11518        if (mHomeProcess != null && (dumpPackage == null
11519                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11520            if (needSep) {
11521                pw.println();
11522                needSep = false;
11523            }
11524            pw.println("  mHomeProcess: " + mHomeProcess);
11525        }
11526        if (mPreviousProcess != null && (dumpPackage == null
11527                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11528            if (needSep) {
11529                pw.println();
11530                needSep = false;
11531            }
11532            pw.println("  mPreviousProcess: " + mPreviousProcess);
11533        }
11534        if (dumpAll) {
11535            StringBuilder sb = new StringBuilder(128);
11536            sb.append("  mPreviousProcessVisibleTime: ");
11537            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11538            pw.println(sb);
11539        }
11540        if (mHeavyWeightProcess != null && (dumpPackage == null
11541                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11542            if (needSep) {
11543                pw.println();
11544                needSep = false;
11545            }
11546            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11547        }
11548        if (dumpPackage == null) {
11549            pw.println("  mConfiguration: " + mConfiguration);
11550        }
11551        if (dumpAll) {
11552            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11553            if (mCompatModePackages.getPackages().size() > 0) {
11554                boolean printed = false;
11555                for (Map.Entry<String, Integer> entry
11556                        : mCompatModePackages.getPackages().entrySet()) {
11557                    String pkg = entry.getKey();
11558                    int mode = entry.getValue();
11559                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11560                        continue;
11561                    }
11562                    if (!printed) {
11563                        pw.println("  mScreenCompatPackages:");
11564                        printed = true;
11565                    }
11566                    pw.print("    "); pw.print(pkg); pw.print(": ");
11567                            pw.print(mode); pw.println();
11568                }
11569            }
11570        }
11571        if (dumpPackage == null) {
11572            if (mSleeping || mWentToSleep || mLockScreenShown) {
11573                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11574                        + " mLockScreenShown " + mLockScreenShown);
11575            }
11576            if (mShuttingDown || mRunningVoice) {
11577                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11578            }
11579        }
11580        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11581                || mOrigWaitForDebugger) {
11582            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11583                    || dumpPackage.equals(mOrigDebugApp)) {
11584                if (needSep) {
11585                    pw.println();
11586                    needSep = false;
11587                }
11588                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11589                        + " mDebugTransient=" + mDebugTransient
11590                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11591            }
11592        }
11593        if (mOpenGlTraceApp != null) {
11594            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11595                if (needSep) {
11596                    pw.println();
11597                    needSep = false;
11598                }
11599                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11600            }
11601        }
11602        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11603                || mProfileFd != null) {
11604            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11605                if (needSep) {
11606                    pw.println();
11607                    needSep = false;
11608                }
11609                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11610                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11611                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11612                        + mAutoStopProfiler);
11613            }
11614        }
11615        if (dumpPackage == null) {
11616            if (mAlwaysFinishActivities || mController != null) {
11617                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11618                        + " mController=" + mController);
11619            }
11620            if (dumpAll) {
11621                pw.println("  Total persistent processes: " + numPers);
11622                pw.println("  mProcessesReady=" + mProcessesReady
11623                        + " mSystemReady=" + mSystemReady);
11624                pw.println("  mBooting=" + mBooting
11625                        + " mBooted=" + mBooted
11626                        + " mFactoryTest=" + mFactoryTest);
11627                pw.print("  mLastPowerCheckRealtime=");
11628                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11629                        pw.println("");
11630                pw.print("  mLastPowerCheckUptime=");
11631                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11632                        pw.println("");
11633                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11634                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11635                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11636                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11637                        + " (" + mLruProcesses.size() + " total)"
11638                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11639                        + " mNumServiceProcs=" + mNumServiceProcs
11640                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11641                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11642                        + " mLastMemoryLevel" + mLastMemoryLevel
11643                        + " mLastNumProcesses" + mLastNumProcesses);
11644                long now = SystemClock.uptimeMillis();
11645                pw.print("  mLastIdleTime=");
11646                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11647                        pw.print(" mLowRamSinceLastIdle=");
11648                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11649                        pw.println();
11650            }
11651        }
11652
11653        if (!printedAnything) {
11654            pw.println("  (nothing)");
11655        }
11656    }
11657
11658    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11659            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11660        if (mProcessesToGc.size() > 0) {
11661            boolean printed = false;
11662            long now = SystemClock.uptimeMillis();
11663            for (int i=0; i<mProcessesToGc.size(); i++) {
11664                ProcessRecord proc = mProcessesToGc.get(i);
11665                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11666                    continue;
11667                }
11668                if (!printed) {
11669                    if (needSep) pw.println();
11670                    needSep = true;
11671                    pw.println("  Processes that are waiting to GC:");
11672                    printed = true;
11673                }
11674                pw.print("    Process "); pw.println(proc);
11675                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11676                        pw.print(", last gced=");
11677                        pw.print(now-proc.lastRequestedGc);
11678                        pw.print(" ms ago, last lowMem=");
11679                        pw.print(now-proc.lastLowMemory);
11680                        pw.println(" ms ago");
11681
11682            }
11683        }
11684        return needSep;
11685    }
11686
11687    void printOomLevel(PrintWriter pw, String name, int adj) {
11688        pw.print("    ");
11689        if (adj >= 0) {
11690            pw.print(' ');
11691            if (adj < 10) pw.print(' ');
11692        } else {
11693            if (adj > -10) pw.print(' ');
11694        }
11695        pw.print(adj);
11696        pw.print(": ");
11697        pw.print(name);
11698        pw.print(" (");
11699        pw.print(mProcessList.getMemLevel(adj)/1024);
11700        pw.println(" kB)");
11701    }
11702
11703    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11704            int opti, boolean dumpAll) {
11705        boolean needSep = false;
11706
11707        if (mLruProcesses.size() > 0) {
11708            if (needSep) pw.println();
11709            needSep = true;
11710            pw.println("  OOM levels:");
11711            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11712            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11713            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11714            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11715            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11716            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11717            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11718            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11719            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11720            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11721            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11722            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11723            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11724
11725            if (needSep) pw.println();
11726            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11727                    pw.print(" total, non-act at ");
11728                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11729                    pw.print(", non-svc at ");
11730                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11731                    pw.println("):");
11732            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11733            needSep = true;
11734        }
11735
11736        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11737
11738        pw.println();
11739        pw.println("  mHomeProcess: " + mHomeProcess);
11740        pw.println("  mPreviousProcess: " + mPreviousProcess);
11741        if (mHeavyWeightProcess != null) {
11742            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11743        }
11744
11745        return true;
11746    }
11747
11748    /**
11749     * There are three ways to call this:
11750     *  - no provider specified: dump all the providers
11751     *  - a flattened component name that matched an existing provider was specified as the
11752     *    first arg: dump that one provider
11753     *  - the first arg isn't the flattened component name of an existing provider:
11754     *    dump all providers whose component contains the first arg as a substring
11755     */
11756    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11757            int opti, boolean dumpAll) {
11758        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11759    }
11760
11761    static class ItemMatcher {
11762        ArrayList<ComponentName> components;
11763        ArrayList<String> strings;
11764        ArrayList<Integer> objects;
11765        boolean all;
11766
11767        ItemMatcher() {
11768            all = true;
11769        }
11770
11771        void build(String name) {
11772            ComponentName componentName = ComponentName.unflattenFromString(name);
11773            if (componentName != null) {
11774                if (components == null) {
11775                    components = new ArrayList<ComponentName>();
11776                }
11777                components.add(componentName);
11778                all = false;
11779            } else {
11780                int objectId = 0;
11781                // Not a '/' separated full component name; maybe an object ID?
11782                try {
11783                    objectId = Integer.parseInt(name, 16);
11784                    if (objects == null) {
11785                        objects = new ArrayList<Integer>();
11786                    }
11787                    objects.add(objectId);
11788                    all = false;
11789                } catch (RuntimeException e) {
11790                    // Not an integer; just do string match.
11791                    if (strings == null) {
11792                        strings = new ArrayList<String>();
11793                    }
11794                    strings.add(name);
11795                    all = false;
11796                }
11797            }
11798        }
11799
11800        int build(String[] args, int opti) {
11801            for (; opti<args.length; opti++) {
11802                String name = args[opti];
11803                if ("--".equals(name)) {
11804                    return opti+1;
11805                }
11806                build(name);
11807            }
11808            return opti;
11809        }
11810
11811        boolean match(Object object, ComponentName comp) {
11812            if (all) {
11813                return true;
11814            }
11815            if (components != null) {
11816                for (int i=0; i<components.size(); i++) {
11817                    if (components.get(i).equals(comp)) {
11818                        return true;
11819                    }
11820                }
11821            }
11822            if (objects != null) {
11823                for (int i=0; i<objects.size(); i++) {
11824                    if (System.identityHashCode(object) == objects.get(i)) {
11825                        return true;
11826                    }
11827                }
11828            }
11829            if (strings != null) {
11830                String flat = comp.flattenToString();
11831                for (int i=0; i<strings.size(); i++) {
11832                    if (flat.contains(strings.get(i))) {
11833                        return true;
11834                    }
11835                }
11836            }
11837            return false;
11838        }
11839    }
11840
11841    /**
11842     * There are three things that cmd can be:
11843     *  - a flattened component name that matches an existing activity
11844     *  - the cmd arg isn't the flattened component name of an existing activity:
11845     *    dump all activity whose component contains the cmd as a substring
11846     *  - A hex number of the ActivityRecord object instance.
11847     */
11848    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11849            int opti, boolean dumpAll) {
11850        ArrayList<ActivityRecord> activities;
11851
11852        synchronized (this) {
11853            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11854        }
11855
11856        if (activities.size() <= 0) {
11857            return false;
11858        }
11859
11860        String[] newArgs = new String[args.length - opti];
11861        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11862
11863        TaskRecord lastTask = null;
11864        boolean needSep = false;
11865        for (int i=activities.size()-1; i>=0; i--) {
11866            ActivityRecord r = activities.get(i);
11867            if (needSep) {
11868                pw.println();
11869            }
11870            needSep = true;
11871            synchronized (this) {
11872                if (lastTask != r.task) {
11873                    lastTask = r.task;
11874                    pw.print("TASK "); pw.print(lastTask.affinity);
11875                            pw.print(" id="); pw.println(lastTask.taskId);
11876                    if (dumpAll) {
11877                        lastTask.dump(pw, "  ");
11878                    }
11879                }
11880            }
11881            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11882        }
11883        return true;
11884    }
11885
11886    /**
11887     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11888     * there is a thread associated with the activity.
11889     */
11890    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11891            final ActivityRecord r, String[] args, boolean dumpAll) {
11892        String innerPrefix = prefix + "  ";
11893        synchronized (this) {
11894            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11895                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11896                    pw.print(" pid=");
11897                    if (r.app != null) pw.println(r.app.pid);
11898                    else pw.println("(not running)");
11899            if (dumpAll) {
11900                r.dump(pw, innerPrefix);
11901            }
11902        }
11903        if (r.app != null && r.app.thread != null) {
11904            // flush anything that is already in the PrintWriter since the thread is going
11905            // to write to the file descriptor directly
11906            pw.flush();
11907            try {
11908                TransferPipe tp = new TransferPipe();
11909                try {
11910                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11911                            r.appToken, innerPrefix, args);
11912                    tp.go(fd);
11913                } finally {
11914                    tp.kill();
11915                }
11916            } catch (IOException e) {
11917                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11918            } catch (RemoteException e) {
11919                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11920            }
11921        }
11922    }
11923
11924    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11925            int opti, boolean dumpAll, String dumpPackage) {
11926        boolean needSep = false;
11927        boolean onlyHistory = false;
11928        boolean printedAnything = false;
11929
11930        if ("history".equals(dumpPackage)) {
11931            if (opti < args.length && "-s".equals(args[opti])) {
11932                dumpAll = false;
11933            }
11934            onlyHistory = true;
11935            dumpPackage = null;
11936        }
11937
11938        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11939        if (!onlyHistory && dumpAll) {
11940            if (mRegisteredReceivers.size() > 0) {
11941                boolean printed = false;
11942                Iterator it = mRegisteredReceivers.values().iterator();
11943                while (it.hasNext()) {
11944                    ReceiverList r = (ReceiverList)it.next();
11945                    if (dumpPackage != null && (r.app == null ||
11946                            !dumpPackage.equals(r.app.info.packageName))) {
11947                        continue;
11948                    }
11949                    if (!printed) {
11950                        pw.println("  Registered Receivers:");
11951                        needSep = true;
11952                        printed = true;
11953                        printedAnything = true;
11954                    }
11955                    pw.print("  * "); pw.println(r);
11956                    r.dump(pw, "    ");
11957                }
11958            }
11959
11960            if (mReceiverResolver.dump(pw, needSep ?
11961                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11962                    "    ", dumpPackage, false)) {
11963                needSep = true;
11964                printedAnything = true;
11965            }
11966        }
11967
11968        for (BroadcastQueue q : mBroadcastQueues) {
11969            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11970            printedAnything |= needSep;
11971        }
11972
11973        needSep = true;
11974
11975        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11976            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11977                if (needSep) {
11978                    pw.println();
11979                }
11980                needSep = true;
11981                printedAnything = true;
11982                pw.print("  Sticky broadcasts for user ");
11983                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11984                StringBuilder sb = new StringBuilder(128);
11985                for (Map.Entry<String, ArrayList<Intent>> ent
11986                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11987                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11988                    if (dumpAll) {
11989                        pw.println(":");
11990                        ArrayList<Intent> intents = ent.getValue();
11991                        final int N = intents.size();
11992                        for (int i=0; i<N; i++) {
11993                            sb.setLength(0);
11994                            sb.append("    Intent: ");
11995                            intents.get(i).toShortString(sb, false, true, false, false);
11996                            pw.println(sb.toString());
11997                            Bundle bundle = intents.get(i).getExtras();
11998                            if (bundle != null) {
11999                                pw.print("      ");
12000                                pw.println(bundle.toString());
12001                            }
12002                        }
12003                    } else {
12004                        pw.println("");
12005                    }
12006                }
12007            }
12008        }
12009
12010        if (!onlyHistory && dumpAll) {
12011            pw.println();
12012            for (BroadcastQueue queue : mBroadcastQueues) {
12013                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
12014                        + queue.mBroadcastsScheduled);
12015            }
12016            pw.println("  mHandler:");
12017            mHandler.dump(new PrintWriterPrinter(pw), "    ");
12018            needSep = true;
12019            printedAnything = true;
12020        }
12021
12022        if (!printedAnything) {
12023            pw.println("  (nothing)");
12024        }
12025    }
12026
12027    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12028            int opti, boolean dumpAll, String dumpPackage) {
12029        boolean needSep;
12030        boolean printedAnything = false;
12031
12032        ItemMatcher matcher = new ItemMatcher();
12033        matcher.build(args, opti);
12034
12035        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12036
12037        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12038        printedAnything |= needSep;
12039
12040        if (mLaunchingProviders.size() > 0) {
12041            boolean printed = false;
12042            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12043                ContentProviderRecord r = mLaunchingProviders.get(i);
12044                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12045                    continue;
12046                }
12047                if (!printed) {
12048                    if (needSep) pw.println();
12049                    needSep = true;
12050                    pw.println("  Launching content providers:");
12051                    printed = true;
12052                    printedAnything = true;
12053                }
12054                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12055                        pw.println(r);
12056            }
12057        }
12058
12059        if (mGrantedUriPermissions.size() > 0) {
12060            boolean printed = false;
12061            int dumpUid = -2;
12062            if (dumpPackage != null) {
12063                try {
12064                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12065                } catch (NameNotFoundException e) {
12066                    dumpUid = -1;
12067                }
12068            }
12069            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12070                int uid = mGrantedUriPermissions.keyAt(i);
12071                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12072                    continue;
12073                }
12074                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12075                if (!printed) {
12076                    if (needSep) pw.println();
12077                    needSep = true;
12078                    pw.println("  Granted Uri Permissions:");
12079                    printed = true;
12080                    printedAnything = true;
12081                }
12082                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12083                for (UriPermission perm : perms.values()) {
12084                    pw.print("    "); pw.println(perm);
12085                    if (dumpAll) {
12086                        perm.dump(pw, "      ");
12087                    }
12088                }
12089            }
12090        }
12091
12092        if (!printedAnything) {
12093            pw.println("  (nothing)");
12094        }
12095    }
12096
12097    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12098            int opti, boolean dumpAll, String dumpPackage) {
12099        boolean printed = false;
12100
12101        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12102
12103        if (mIntentSenderRecords.size() > 0) {
12104            Iterator<WeakReference<PendingIntentRecord>> it
12105                    = mIntentSenderRecords.values().iterator();
12106            while (it.hasNext()) {
12107                WeakReference<PendingIntentRecord> ref = it.next();
12108                PendingIntentRecord rec = ref != null ? ref.get(): null;
12109                if (dumpPackage != null && (rec == null
12110                        || !dumpPackage.equals(rec.key.packageName))) {
12111                    continue;
12112                }
12113                printed = true;
12114                if (rec != null) {
12115                    pw.print("  * "); pw.println(rec);
12116                    if (dumpAll) {
12117                        rec.dump(pw, "    ");
12118                    }
12119                } else {
12120                    pw.print("  * "); pw.println(ref);
12121                }
12122            }
12123        }
12124
12125        if (!printed) {
12126            pw.println("  (nothing)");
12127        }
12128    }
12129
12130    private static final int dumpProcessList(PrintWriter pw,
12131            ActivityManagerService service, List list,
12132            String prefix, String normalLabel, String persistentLabel,
12133            String dumpPackage) {
12134        int numPers = 0;
12135        final int N = list.size()-1;
12136        for (int i=N; i>=0; i--) {
12137            ProcessRecord r = (ProcessRecord)list.get(i);
12138            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12139                continue;
12140            }
12141            pw.println(String.format("%s%s #%2d: %s",
12142                    prefix, (r.persistent ? persistentLabel : normalLabel),
12143                    i, r.toString()));
12144            if (r.persistent) {
12145                numPers++;
12146            }
12147        }
12148        return numPers;
12149    }
12150
12151    private static final boolean dumpProcessOomList(PrintWriter pw,
12152            ActivityManagerService service, List<ProcessRecord> origList,
12153            String prefix, String normalLabel, String persistentLabel,
12154            boolean inclDetails, String dumpPackage) {
12155
12156        ArrayList<Pair<ProcessRecord, Integer>> list
12157                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12158        for (int i=0; i<origList.size(); i++) {
12159            ProcessRecord r = origList.get(i);
12160            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12161                continue;
12162            }
12163            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12164        }
12165
12166        if (list.size() <= 0) {
12167            return false;
12168        }
12169
12170        Comparator<Pair<ProcessRecord, Integer>> comparator
12171                = new Comparator<Pair<ProcessRecord, Integer>>() {
12172            @Override
12173            public int compare(Pair<ProcessRecord, Integer> object1,
12174                    Pair<ProcessRecord, Integer> object2) {
12175                if (object1.first.setAdj != object2.first.setAdj) {
12176                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12177                }
12178                if (object1.second.intValue() != object2.second.intValue()) {
12179                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12180                }
12181                return 0;
12182            }
12183        };
12184
12185        Collections.sort(list, comparator);
12186
12187        final long curRealtime = SystemClock.elapsedRealtime();
12188        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12189        final long curUptime = SystemClock.uptimeMillis();
12190        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12191
12192        for (int i=list.size()-1; i>=0; i--) {
12193            ProcessRecord r = list.get(i).first;
12194            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12195            char schedGroup;
12196            switch (r.setSchedGroup) {
12197                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12198                    schedGroup = 'B';
12199                    break;
12200                case Process.THREAD_GROUP_DEFAULT:
12201                    schedGroup = 'F';
12202                    break;
12203                default:
12204                    schedGroup = '?';
12205                    break;
12206            }
12207            char foreground;
12208            if (r.foregroundActivities) {
12209                foreground = 'A';
12210            } else if (r.foregroundServices) {
12211                foreground = 'S';
12212            } else {
12213                foreground = ' ';
12214            }
12215            String procState = ProcessList.makeProcStateString(r.curProcState);
12216            pw.print(prefix);
12217            pw.print(r.persistent ? persistentLabel : normalLabel);
12218            pw.print(" #");
12219            int num = (origList.size()-1)-list.get(i).second;
12220            if (num < 10) pw.print(' ');
12221            pw.print(num);
12222            pw.print(": ");
12223            pw.print(oomAdj);
12224            pw.print(' ');
12225            pw.print(schedGroup);
12226            pw.print('/');
12227            pw.print(foreground);
12228            pw.print('/');
12229            pw.print(procState);
12230            pw.print(" trm:");
12231            if (r.trimMemoryLevel < 10) pw.print(' ');
12232            pw.print(r.trimMemoryLevel);
12233            pw.print(' ');
12234            pw.print(r.toShortString());
12235            pw.print(" (");
12236            pw.print(r.adjType);
12237            pw.println(')');
12238            if (r.adjSource != null || r.adjTarget != null) {
12239                pw.print(prefix);
12240                pw.print("    ");
12241                if (r.adjTarget instanceof ComponentName) {
12242                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12243                } else if (r.adjTarget != null) {
12244                    pw.print(r.adjTarget.toString());
12245                } else {
12246                    pw.print("{null}");
12247                }
12248                pw.print("<=");
12249                if (r.adjSource instanceof ProcessRecord) {
12250                    pw.print("Proc{");
12251                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12252                    pw.println("}");
12253                } else if (r.adjSource != null) {
12254                    pw.println(r.adjSource.toString());
12255                } else {
12256                    pw.println("{null}");
12257                }
12258            }
12259            if (inclDetails) {
12260                pw.print(prefix);
12261                pw.print("    ");
12262                pw.print("oom: max="); pw.print(r.maxAdj);
12263                pw.print(" curRaw="); pw.print(r.curRawAdj);
12264                pw.print(" setRaw="); pw.print(r.setRawAdj);
12265                pw.print(" cur="); pw.print(r.curAdj);
12266                pw.print(" set="); pw.println(r.setAdj);
12267                pw.print(prefix);
12268                pw.print("    ");
12269                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12270                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12271                pw.print(" lastPss="); pw.print(r.lastPss);
12272                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12273                pw.print(prefix);
12274                pw.print("    ");
12275                pw.print("keeping="); pw.print(r.keeping);
12276                pw.print(" cached="); pw.print(r.cached);
12277                pw.print(" empty="); pw.print(r.empty);
12278                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12279
12280                if (!r.keeping) {
12281                    if (r.lastWakeTime != 0) {
12282                        long wtime;
12283                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12284                        synchronized (stats) {
12285                            wtime = stats.getProcessWakeTime(r.info.uid,
12286                                    r.pid, curRealtime);
12287                        }
12288                        long timeUsed = wtime - r.lastWakeTime;
12289                        pw.print(prefix);
12290                        pw.print("    ");
12291                        pw.print("keep awake over ");
12292                        TimeUtils.formatDuration(realtimeSince, pw);
12293                        pw.print(" used ");
12294                        TimeUtils.formatDuration(timeUsed, pw);
12295                        pw.print(" (");
12296                        pw.print((timeUsed*100)/realtimeSince);
12297                        pw.println("%)");
12298                    }
12299                    if (r.lastCpuTime != 0) {
12300                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12301                        pw.print(prefix);
12302                        pw.print("    ");
12303                        pw.print("run cpu over ");
12304                        TimeUtils.formatDuration(uptimeSince, pw);
12305                        pw.print(" used ");
12306                        TimeUtils.formatDuration(timeUsed, pw);
12307                        pw.print(" (");
12308                        pw.print((timeUsed*100)/uptimeSince);
12309                        pw.println("%)");
12310                    }
12311                }
12312            }
12313        }
12314        return true;
12315    }
12316
12317    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12318        ArrayList<ProcessRecord> procs;
12319        synchronized (this) {
12320            if (args != null && args.length > start
12321                    && args[start].charAt(0) != '-') {
12322                procs = new ArrayList<ProcessRecord>();
12323                int pid = -1;
12324                try {
12325                    pid = Integer.parseInt(args[start]);
12326                } catch (NumberFormatException e) {
12327                }
12328                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12329                    ProcessRecord proc = mLruProcesses.get(i);
12330                    if (proc.pid == pid) {
12331                        procs.add(proc);
12332                    } else if (proc.processName.equals(args[start])) {
12333                        procs.add(proc);
12334                    }
12335                }
12336                if (procs.size() <= 0) {
12337                    return null;
12338                }
12339            } else {
12340                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12341            }
12342        }
12343        return procs;
12344    }
12345
12346    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12347            PrintWriter pw, String[] args) {
12348        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12349        if (procs == null) {
12350            pw.println("No process found for: " + args[0]);
12351            return;
12352        }
12353
12354        long uptime = SystemClock.uptimeMillis();
12355        long realtime = SystemClock.elapsedRealtime();
12356        pw.println("Applications Graphics Acceleration Info:");
12357        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12358
12359        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12360            ProcessRecord r = procs.get(i);
12361            if (r.thread != null) {
12362                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12363                pw.flush();
12364                try {
12365                    TransferPipe tp = new TransferPipe();
12366                    try {
12367                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12368                        tp.go(fd);
12369                    } finally {
12370                        tp.kill();
12371                    }
12372                } catch (IOException e) {
12373                    pw.println("Failure while dumping the app: " + r);
12374                    pw.flush();
12375                } catch (RemoteException e) {
12376                    pw.println("Got a RemoteException while dumping the app " + r);
12377                    pw.flush();
12378                }
12379            }
12380        }
12381    }
12382
12383    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12384        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12385        if (procs == null) {
12386            pw.println("No process found for: " + args[0]);
12387            return;
12388        }
12389
12390        pw.println("Applications Database Info:");
12391
12392        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12393            ProcessRecord r = procs.get(i);
12394            if (r.thread != null) {
12395                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12396                pw.flush();
12397                try {
12398                    TransferPipe tp = new TransferPipe();
12399                    try {
12400                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12401                        tp.go(fd);
12402                    } finally {
12403                        tp.kill();
12404                    }
12405                } catch (IOException e) {
12406                    pw.println("Failure while dumping the app: " + r);
12407                    pw.flush();
12408                } catch (RemoteException e) {
12409                    pw.println("Got a RemoteException while dumping the app " + r);
12410                    pw.flush();
12411                }
12412            }
12413        }
12414    }
12415
12416    final static class MemItem {
12417        final boolean isProc;
12418        final String label;
12419        final String shortLabel;
12420        final long pss;
12421        final int id;
12422        final boolean hasActivities;
12423        ArrayList<MemItem> subitems;
12424
12425        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12426                boolean _hasActivities) {
12427            isProc = true;
12428            label = _label;
12429            shortLabel = _shortLabel;
12430            pss = _pss;
12431            id = _id;
12432            hasActivities = _hasActivities;
12433        }
12434
12435        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12436            isProc = false;
12437            label = _label;
12438            shortLabel = _shortLabel;
12439            pss = _pss;
12440            id = _id;
12441            hasActivities = false;
12442        }
12443    }
12444
12445    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12446            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12447        if (sort && !isCompact) {
12448            Collections.sort(items, new Comparator<MemItem>() {
12449                @Override
12450                public int compare(MemItem lhs, MemItem rhs) {
12451                    if (lhs.pss < rhs.pss) {
12452                        return 1;
12453                    } else if (lhs.pss > rhs.pss) {
12454                        return -1;
12455                    }
12456                    return 0;
12457                }
12458            });
12459        }
12460
12461        for (int i=0; i<items.size(); i++) {
12462            MemItem mi = items.get(i);
12463            if (!isCompact) {
12464                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12465            } else if (mi.isProc) {
12466                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12467                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12468                pw.println(mi.hasActivities ? ",a" : ",e");
12469            } else {
12470                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12471                pw.println(mi.pss);
12472            }
12473            if (mi.subitems != null) {
12474                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12475                        true, isCompact);
12476            }
12477        }
12478    }
12479
12480    // These are in KB.
12481    static final long[] DUMP_MEM_BUCKETS = new long[] {
12482        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12483        120*1024, 160*1024, 200*1024,
12484        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12485        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12486    };
12487
12488    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12489            boolean stackLike) {
12490        int start = label.lastIndexOf('.');
12491        if (start >= 0) start++;
12492        else start = 0;
12493        int end = label.length();
12494        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12495            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12496                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12497                out.append(bucket);
12498                out.append(stackLike ? "MB." : "MB ");
12499                out.append(label, start, end);
12500                return;
12501            }
12502        }
12503        out.append(memKB/1024);
12504        out.append(stackLike ? "MB." : "MB ");
12505        out.append(label, start, end);
12506    }
12507
12508    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12509            ProcessList.NATIVE_ADJ,
12510            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12511            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12512            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12513            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12514            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12515    };
12516    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12517            "Native",
12518            "System", "Persistent", "Foreground",
12519            "Visible", "Perceptible",
12520            "Heavy Weight", "Backup",
12521            "A Services", "Home",
12522            "Previous", "B Services", "Cached"
12523    };
12524    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12525            "native",
12526            "sys", "pers", "fore",
12527            "vis", "percept",
12528            "heavy", "backup",
12529            "servicea", "home",
12530            "prev", "serviceb", "cached"
12531    };
12532
12533    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12534            long realtime, boolean isCheckinRequest, boolean isCompact) {
12535        if (isCheckinRequest || isCompact) {
12536            // short checkin version
12537            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12538        } else {
12539            pw.println("Applications Memory Usage (kB):");
12540            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12541        }
12542    }
12543
12544    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12545            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12546        boolean dumpDetails = false;
12547        boolean dumpFullDetails = false;
12548        boolean dumpDalvik = false;
12549        boolean oomOnly = false;
12550        boolean isCompact = false;
12551        boolean localOnly = false;
12552
12553        int opti = 0;
12554        while (opti < args.length) {
12555            String opt = args[opti];
12556            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12557                break;
12558            }
12559            opti++;
12560            if ("-a".equals(opt)) {
12561                dumpDetails = true;
12562                dumpFullDetails = true;
12563                dumpDalvik = true;
12564            } else if ("-d".equals(opt)) {
12565                dumpDalvik = true;
12566            } else if ("-c".equals(opt)) {
12567                isCompact = true;
12568            } else if ("--oom".equals(opt)) {
12569                oomOnly = true;
12570            } else if ("--local".equals(opt)) {
12571                localOnly = true;
12572            } else if ("-h".equals(opt)) {
12573                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12574                pw.println("  -a: include all available information for each process.");
12575                pw.println("  -d: include dalvik details when dumping process details.");
12576                pw.println("  -c: dump in a compact machine-parseable representation.");
12577                pw.println("  --oom: only show processes organized by oom adj.");
12578                pw.println("  --local: only collect details locally, don't call process.");
12579                pw.println("If [process] is specified it can be the name or ");
12580                pw.println("pid of a specific process to dump.");
12581                return;
12582            } else {
12583                pw.println("Unknown argument: " + opt + "; use -h for help");
12584            }
12585        }
12586
12587        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12588        long uptime = SystemClock.uptimeMillis();
12589        long realtime = SystemClock.elapsedRealtime();
12590        final long[] tmpLong = new long[1];
12591
12592        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12593        if (procs == null) {
12594            // No Java processes.  Maybe they want to print a native process.
12595            if (args != null && args.length > opti
12596                    && args[opti].charAt(0) != '-') {
12597                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12598                        = new ArrayList<ProcessCpuTracker.Stats>();
12599                updateCpuStatsNow();
12600                int findPid = -1;
12601                try {
12602                    findPid = Integer.parseInt(args[opti]);
12603                } catch (NumberFormatException e) {
12604                }
12605                synchronized (mProcessCpuThread) {
12606                    final int N = mProcessCpuTracker.countStats();
12607                    for (int i=0; i<N; i++) {
12608                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12609                        if (st.pid == findPid || (st.baseName != null
12610                                && st.baseName.equals(args[opti]))) {
12611                            nativeProcs.add(st);
12612                        }
12613                    }
12614                }
12615                if (nativeProcs.size() > 0) {
12616                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12617                            isCompact);
12618                    Debug.MemoryInfo mi = null;
12619                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12620                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12621                        final int pid = r.pid;
12622                        if (!isCheckinRequest && dumpDetails) {
12623                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12624                        }
12625                        if (mi == null) {
12626                            mi = new Debug.MemoryInfo();
12627                        }
12628                        if (dumpDetails || (!brief && !oomOnly)) {
12629                            Debug.getMemoryInfo(pid, mi);
12630                        } else {
12631                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12632                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12633                        }
12634                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12635                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12636                        if (isCheckinRequest) {
12637                            pw.println();
12638                        }
12639                    }
12640                    return;
12641                }
12642            }
12643            pw.println("No process found for: " + args[opti]);
12644            return;
12645        }
12646
12647        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12648            dumpDetails = true;
12649        }
12650
12651        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12652
12653        String[] innerArgs = new String[args.length-opti];
12654        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12655
12656        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12657        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12658        long nativePss=0, dalvikPss=0, otherPss=0;
12659        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12660
12661        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12662        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12663                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12664
12665        long totalPss = 0;
12666        long cachedPss = 0;
12667
12668        Debug.MemoryInfo mi = null;
12669        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12670            final ProcessRecord r = procs.get(i);
12671            final IApplicationThread thread;
12672            final int pid;
12673            final int oomAdj;
12674            final boolean hasActivities;
12675            synchronized (this) {
12676                thread = r.thread;
12677                pid = r.pid;
12678                oomAdj = r.getSetAdjWithServices();
12679                hasActivities = r.activities.size() > 0;
12680            }
12681            if (thread != null) {
12682                if (!isCheckinRequest && dumpDetails) {
12683                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12684                }
12685                if (mi == null) {
12686                    mi = new Debug.MemoryInfo();
12687                }
12688                if (dumpDetails || (!brief && !oomOnly)) {
12689                    Debug.getMemoryInfo(pid, mi);
12690                } else {
12691                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12692                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12693                }
12694                if (dumpDetails) {
12695                    if (localOnly) {
12696                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12697                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12698                        if (isCheckinRequest) {
12699                            pw.println();
12700                        }
12701                    } else {
12702                        try {
12703                            pw.flush();
12704                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12705                                    dumpDalvik, innerArgs);
12706                        } catch (RemoteException e) {
12707                            if (!isCheckinRequest) {
12708                                pw.println("Got RemoteException!");
12709                                pw.flush();
12710                            }
12711                        }
12712                    }
12713                }
12714
12715                final long myTotalPss = mi.getTotalPss();
12716                final long myTotalUss = mi.getTotalUss();
12717
12718                synchronized (this) {
12719                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12720                        // Record this for posterity if the process has been stable.
12721                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12722                    }
12723                }
12724
12725                if (!isCheckinRequest && mi != null) {
12726                    totalPss += myTotalPss;
12727                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12728                            (hasActivities ? " / activities)" : ")"),
12729                            r.processName, myTotalPss, pid, hasActivities);
12730                    procMems.add(pssItem);
12731                    procMemsMap.put(pid, pssItem);
12732
12733                    nativePss += mi.nativePss;
12734                    dalvikPss += mi.dalvikPss;
12735                    otherPss += mi.otherPss;
12736                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12737                        long mem = mi.getOtherPss(j);
12738                        miscPss[j] += mem;
12739                        otherPss -= mem;
12740                    }
12741
12742                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12743                        cachedPss += myTotalPss;
12744                    }
12745
12746                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12747                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12748                                || oomIndex == (oomPss.length-1)) {
12749                            oomPss[oomIndex] += myTotalPss;
12750                            if (oomProcs[oomIndex] == null) {
12751                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12752                            }
12753                            oomProcs[oomIndex].add(pssItem);
12754                            break;
12755                        }
12756                    }
12757                }
12758            }
12759        }
12760
12761        long nativeProcTotalPss = 0;
12762
12763        if (!isCheckinRequest && procs.size() > 1) {
12764            // If we are showing aggregations, also look for native processes to
12765            // include so that our aggregations are more accurate.
12766            updateCpuStatsNow();
12767            synchronized (mProcessCpuThread) {
12768                final int N = mProcessCpuTracker.countStats();
12769                for (int i=0; i<N; i++) {
12770                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12771                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12772                        if (mi == null) {
12773                            mi = new Debug.MemoryInfo();
12774                        }
12775                        if (!brief && !oomOnly) {
12776                            Debug.getMemoryInfo(st.pid, mi);
12777                        } else {
12778                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12779                            mi.nativePrivateDirty = (int)tmpLong[0];
12780                        }
12781
12782                        final long myTotalPss = mi.getTotalPss();
12783                        totalPss += myTotalPss;
12784                        nativeProcTotalPss += myTotalPss;
12785
12786                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12787                                st.name, myTotalPss, st.pid, false);
12788                        procMems.add(pssItem);
12789
12790                        nativePss += mi.nativePss;
12791                        dalvikPss += mi.dalvikPss;
12792                        otherPss += mi.otherPss;
12793                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12794                            long mem = mi.getOtherPss(j);
12795                            miscPss[j] += mem;
12796                            otherPss -= mem;
12797                        }
12798                        oomPss[0] += myTotalPss;
12799                        if (oomProcs[0] == null) {
12800                            oomProcs[0] = new ArrayList<MemItem>();
12801                        }
12802                        oomProcs[0].add(pssItem);
12803                    }
12804                }
12805            }
12806
12807            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12808
12809            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12810            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12811            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12812            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12813                String label = Debug.MemoryInfo.getOtherLabel(j);
12814                catMems.add(new MemItem(label, label, miscPss[j], j));
12815            }
12816
12817            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12818            for (int j=0; j<oomPss.length; j++) {
12819                if (oomPss[j] != 0) {
12820                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12821                            : DUMP_MEM_OOM_LABEL[j];
12822                    MemItem item = new MemItem(label, label, oomPss[j],
12823                            DUMP_MEM_OOM_ADJ[j]);
12824                    item.subitems = oomProcs[j];
12825                    oomMems.add(item);
12826                }
12827            }
12828
12829            if (!brief && !oomOnly && !isCompact) {
12830                pw.println();
12831                pw.println("Total PSS by process:");
12832                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12833                pw.println();
12834            }
12835            if (!isCompact) {
12836                pw.println("Total PSS by OOM adjustment:");
12837            }
12838            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12839            if (!brief && !oomOnly) {
12840                PrintWriter out = categoryPw != null ? categoryPw : pw;
12841                if (!isCompact) {
12842                    out.println();
12843                    out.println("Total PSS by category:");
12844                }
12845                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12846            }
12847            if (!isCompact) {
12848                pw.println();
12849            }
12850            MemInfoReader memInfo = new MemInfoReader();
12851            memInfo.readMemInfo();
12852            if (nativeProcTotalPss > 0) {
12853                synchronized (this) {
12854                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
12855                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
12856                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
12857                            nativeProcTotalPss);
12858                }
12859            }
12860            if (!brief) {
12861                if (!isCompact) {
12862                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12863                    pw.print(" kB (status ");
12864                    switch (mLastMemoryLevel) {
12865                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12866                            pw.println("normal)");
12867                            break;
12868                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12869                            pw.println("moderate)");
12870                            break;
12871                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12872                            pw.println("low)");
12873                            break;
12874                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12875                            pw.println("critical)");
12876                            break;
12877                        default:
12878                            pw.print(mLastMemoryLevel);
12879                            pw.println(")");
12880                            break;
12881                    }
12882                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12883                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12884                            pw.print(cachedPss); pw.print(" cached pss + ");
12885                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12886                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12887                } else {
12888                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12889                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12890                            + memInfo.getFreeSizeKb()); pw.print(",");
12891                    pw.println(totalPss - cachedPss);
12892                }
12893            }
12894            if (!isCompact) {
12895                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12896                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12897                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12898                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12899                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12900                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12901                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12902                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12903                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12904                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12905                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12906            }
12907            if (!brief) {
12908                if (memInfo.getZramTotalSizeKb() != 0) {
12909                    if (!isCompact) {
12910                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12911                                pw.print(" kB physical used for ");
12912                                pw.print(memInfo.getSwapTotalSizeKb()
12913                                        - memInfo.getSwapFreeSizeKb());
12914                                pw.print(" kB in swap (");
12915                                pw.print(memInfo.getSwapTotalSizeKb());
12916                                pw.println(" kB total swap)");
12917                    } else {
12918                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12919                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12920                                pw.println(memInfo.getSwapFreeSizeKb());
12921                    }
12922                }
12923                final int[] SINGLE_LONG_FORMAT = new int[] {
12924                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12925                };
12926                long[] longOut = new long[1];
12927                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12928                        SINGLE_LONG_FORMAT, null, longOut, null);
12929                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12930                longOut[0] = 0;
12931                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12932                        SINGLE_LONG_FORMAT, null, longOut, null);
12933                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12934                longOut[0] = 0;
12935                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12936                        SINGLE_LONG_FORMAT, null, longOut, null);
12937                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12938                longOut[0] = 0;
12939                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12940                        SINGLE_LONG_FORMAT, null, longOut, null);
12941                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12942                if (!isCompact) {
12943                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12944                        pw.print("      KSM: "); pw.print(sharing);
12945                                pw.print(" kB saved from shared ");
12946                                pw.print(shared); pw.println(" kB");
12947                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12948                                pw.print(voltile); pw.println(" kB volatile");
12949                    }
12950                    pw.print("   Tuning: ");
12951                    pw.print(ActivityManager.staticGetMemoryClass());
12952                    pw.print(" (large ");
12953                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12954                    pw.print("), oom ");
12955                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12956                    pw.print(" kB");
12957                    pw.print(", restore limit ");
12958                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12959                    pw.print(" kB");
12960                    if (ActivityManager.isLowRamDeviceStatic()) {
12961                        pw.print(" (low-ram)");
12962                    }
12963                    if (ActivityManager.isHighEndGfx()) {
12964                        pw.print(" (high-end-gfx)");
12965                    }
12966                    pw.println();
12967                } else {
12968                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12969                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12970                    pw.println(voltile);
12971                    pw.print("tuning,");
12972                    pw.print(ActivityManager.staticGetMemoryClass());
12973                    pw.print(',');
12974                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12975                    pw.print(',');
12976                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12977                    if (ActivityManager.isLowRamDeviceStatic()) {
12978                        pw.print(",low-ram");
12979                    }
12980                    if (ActivityManager.isHighEndGfx()) {
12981                        pw.print(",high-end-gfx");
12982                    }
12983                    pw.println();
12984                }
12985            }
12986        }
12987    }
12988
12989    /**
12990     * Searches array of arguments for the specified string
12991     * @param args array of argument strings
12992     * @param value value to search for
12993     * @return true if the value is contained in the array
12994     */
12995    private static boolean scanArgs(String[] args, String value) {
12996        if (args != null) {
12997            for (String arg : args) {
12998                if (value.equals(arg)) {
12999                    return true;
13000                }
13001            }
13002        }
13003        return false;
13004    }
13005
13006    private final boolean removeDyingProviderLocked(ProcessRecord proc,
13007            ContentProviderRecord cpr, boolean always) {
13008        final boolean inLaunching = mLaunchingProviders.contains(cpr);
13009
13010        if (!inLaunching || always) {
13011            synchronized (cpr) {
13012                cpr.launchingApp = null;
13013                cpr.notifyAll();
13014            }
13015            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
13016            String names[] = cpr.info.authority.split(";");
13017            for (int j = 0; j < names.length; j++) {
13018                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
13019            }
13020        }
13021
13022        for (int i=0; i<cpr.connections.size(); i++) {
13023            ContentProviderConnection conn = cpr.connections.get(i);
13024            if (conn.waiting) {
13025                // If this connection is waiting for the provider, then we don't
13026                // need to mess with its process unless we are always removing
13027                // or for some reason the provider is not currently launching.
13028                if (inLaunching && !always) {
13029                    continue;
13030                }
13031            }
13032            ProcessRecord capp = conn.client;
13033            conn.dead = true;
13034            if (conn.stableCount > 0) {
13035                if (!capp.persistent && capp.thread != null
13036                        && capp.pid != 0
13037                        && capp.pid != MY_PID) {
13038                    killUnneededProcessLocked(capp, "depends on provider "
13039                            + cpr.name.flattenToShortString()
13040                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13041                }
13042            } else if (capp.thread != null && conn.provider.provider != null) {
13043                try {
13044                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13045                } catch (RemoteException e) {
13046                }
13047                // In the protocol here, we don't expect the client to correctly
13048                // clean up this connection, we'll just remove it.
13049                cpr.connections.remove(i);
13050                conn.client.conProviders.remove(conn);
13051            }
13052        }
13053
13054        if (inLaunching && always) {
13055            mLaunchingProviders.remove(cpr);
13056        }
13057        return inLaunching;
13058    }
13059
13060    /**
13061     * Main code for cleaning up a process when it has gone away.  This is
13062     * called both as a result of the process dying, or directly when stopping
13063     * a process when running in single process mode.
13064     */
13065    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13066            boolean restarting, boolean allowRestart, int index) {
13067        if (index >= 0) {
13068            removeLruProcessLocked(app);
13069            ProcessList.remove(app.pid);
13070        }
13071
13072        mProcessesToGc.remove(app);
13073        mPendingPssProcesses.remove(app);
13074
13075        // Dismiss any open dialogs.
13076        if (app.crashDialog != null && !app.forceCrashReport) {
13077            app.crashDialog.dismiss();
13078            app.crashDialog = null;
13079        }
13080        if (app.anrDialog != null) {
13081            app.anrDialog.dismiss();
13082            app.anrDialog = null;
13083        }
13084        if (app.waitDialog != null) {
13085            app.waitDialog.dismiss();
13086            app.waitDialog = null;
13087        }
13088
13089        app.crashing = false;
13090        app.notResponding = false;
13091
13092        app.resetPackageList(mProcessStats);
13093        app.unlinkDeathRecipient();
13094        app.makeInactive(mProcessStats);
13095        app.forcingToForeground = null;
13096        updateProcessForegroundLocked(app, false, false);
13097        app.foregroundActivities = false;
13098        app.hasShownUi = false;
13099        app.treatLikeActivity = false;
13100        app.hasAboveClient = false;
13101        app.hasClientActivities = false;
13102
13103        mServices.killServicesLocked(app, allowRestart);
13104
13105        boolean restart = false;
13106
13107        // Remove published content providers.
13108        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13109            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13110            final boolean always = app.bad || !allowRestart;
13111            if (removeDyingProviderLocked(app, cpr, always) || always) {
13112                // We left the provider in the launching list, need to
13113                // restart it.
13114                restart = true;
13115            }
13116
13117            cpr.provider = null;
13118            cpr.proc = null;
13119        }
13120        app.pubProviders.clear();
13121
13122        // Take care of any launching providers waiting for this process.
13123        if (checkAppInLaunchingProvidersLocked(app, false)) {
13124            restart = true;
13125        }
13126
13127        // Unregister from connected content providers.
13128        if (!app.conProviders.isEmpty()) {
13129            for (int i=0; i<app.conProviders.size(); i++) {
13130                ContentProviderConnection conn = app.conProviders.get(i);
13131                conn.provider.connections.remove(conn);
13132            }
13133            app.conProviders.clear();
13134        }
13135
13136        // At this point there may be remaining entries in mLaunchingProviders
13137        // where we were the only one waiting, so they are no longer of use.
13138        // Look for these and clean up if found.
13139        // XXX Commented out for now.  Trying to figure out a way to reproduce
13140        // the actual situation to identify what is actually going on.
13141        if (false) {
13142            for (int i=0; i<mLaunchingProviders.size(); i++) {
13143                ContentProviderRecord cpr = (ContentProviderRecord)
13144                        mLaunchingProviders.get(i);
13145                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13146                    synchronized (cpr) {
13147                        cpr.launchingApp = null;
13148                        cpr.notifyAll();
13149                    }
13150                }
13151            }
13152        }
13153
13154        skipCurrentReceiverLocked(app);
13155
13156        // Unregister any receivers.
13157        for (int i=app.receivers.size()-1; i>=0; i--) {
13158            removeReceiverLocked(app.receivers.valueAt(i));
13159        }
13160        app.receivers.clear();
13161
13162        // If the app is undergoing backup, tell the backup manager about it
13163        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13164            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13165                    + mBackupTarget.appInfo + " died during backup");
13166            try {
13167                IBackupManager bm = IBackupManager.Stub.asInterface(
13168                        ServiceManager.getService(Context.BACKUP_SERVICE));
13169                bm.agentDisconnected(app.info.packageName);
13170            } catch (RemoteException e) {
13171                // can't happen; backup manager is local
13172            }
13173        }
13174
13175        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13176            ProcessChangeItem item = mPendingProcessChanges.get(i);
13177            if (item.pid == app.pid) {
13178                mPendingProcessChanges.remove(i);
13179                mAvailProcessChanges.add(item);
13180            }
13181        }
13182        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13183
13184        // If the caller is restarting this app, then leave it in its
13185        // current lists and let the caller take care of it.
13186        if (restarting) {
13187            return;
13188        }
13189
13190        if (!app.persistent || app.isolated) {
13191            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13192                    "Removing non-persistent process during cleanup: " + app);
13193            mProcessNames.remove(app.processName, app.uid);
13194            mIsolatedProcesses.remove(app.uid);
13195            if (mHeavyWeightProcess == app) {
13196                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13197                        mHeavyWeightProcess.userId, 0));
13198                mHeavyWeightProcess = null;
13199            }
13200        } else if (!app.removed) {
13201            // This app is persistent, so we need to keep its record around.
13202            // If it is not already on the pending app list, add it there
13203            // and start a new process for it.
13204            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13205                mPersistentStartingProcesses.add(app);
13206                restart = true;
13207            }
13208        }
13209        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13210                "Clean-up removing on hold: " + app);
13211        mProcessesOnHold.remove(app);
13212
13213        if (app == mHomeProcess) {
13214            mHomeProcess = null;
13215        }
13216        if (app == mPreviousProcess) {
13217            mPreviousProcess = null;
13218        }
13219
13220        if (restart && !app.isolated) {
13221            // We have components that still need to be running in the
13222            // process, so re-launch it.
13223            mProcessNames.put(app.processName, app.uid, app);
13224            startProcessLocked(app, "restart", app.processName, null /* ABI override */);
13225        } else if (app.pid > 0 && app.pid != MY_PID) {
13226            // Goodbye!
13227            boolean removed;
13228            synchronized (mPidsSelfLocked) {
13229                mPidsSelfLocked.remove(app.pid);
13230                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13231            }
13232            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
13233                    app.processName, app.info.uid);
13234            if (app.isolated) {
13235                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13236            }
13237            app.setPid(0);
13238        }
13239    }
13240
13241    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13242        // Look through the content providers we are waiting to have launched,
13243        // and if any run in this process then either schedule a restart of
13244        // the process or kill the client waiting for it if this process has
13245        // gone bad.
13246        int NL = mLaunchingProviders.size();
13247        boolean restart = false;
13248        for (int i=0; i<NL; i++) {
13249            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13250            if (cpr.launchingApp == app) {
13251                if (!alwaysBad && !app.bad) {
13252                    restart = true;
13253                } else {
13254                    removeDyingProviderLocked(app, cpr, true);
13255                    // cpr should have been removed from mLaunchingProviders
13256                    NL = mLaunchingProviders.size();
13257                    i--;
13258                }
13259            }
13260        }
13261        return restart;
13262    }
13263
13264    // =========================================================
13265    // SERVICES
13266    // =========================================================
13267
13268    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13269            int flags) {
13270        enforceNotIsolatedCaller("getServices");
13271        synchronized (this) {
13272            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13273        }
13274    }
13275
13276    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13277        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13278        synchronized (this) {
13279            return mServices.getRunningServiceControlPanelLocked(name);
13280        }
13281    }
13282
13283    public ComponentName startService(IApplicationThread caller, Intent service,
13284            String resolvedType, int userId) {
13285        enforceNotIsolatedCaller("startService");
13286        // Refuse possible leaked file descriptors
13287        if (service != null && service.hasFileDescriptors() == true) {
13288            throw new IllegalArgumentException("File descriptors passed in Intent");
13289        }
13290
13291        if (DEBUG_SERVICE)
13292            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13293        synchronized(this) {
13294            final int callingPid = Binder.getCallingPid();
13295            final int callingUid = Binder.getCallingUid();
13296            final long origId = Binder.clearCallingIdentity();
13297            ComponentName res = mServices.startServiceLocked(caller, service,
13298                    resolvedType, callingPid, callingUid, userId);
13299            Binder.restoreCallingIdentity(origId);
13300            return res;
13301        }
13302    }
13303
13304    ComponentName startServiceInPackage(int uid,
13305            Intent service, String resolvedType, int userId) {
13306        synchronized(this) {
13307            if (DEBUG_SERVICE)
13308                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13309            final long origId = Binder.clearCallingIdentity();
13310            ComponentName res = mServices.startServiceLocked(null, service,
13311                    resolvedType, -1, uid, userId);
13312            Binder.restoreCallingIdentity(origId);
13313            return res;
13314        }
13315    }
13316
13317    public int stopService(IApplicationThread caller, Intent service,
13318            String resolvedType, int userId) {
13319        enforceNotIsolatedCaller("stopService");
13320        // Refuse possible leaked file descriptors
13321        if (service != null && service.hasFileDescriptors() == true) {
13322            throw new IllegalArgumentException("File descriptors passed in Intent");
13323        }
13324
13325        synchronized(this) {
13326            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13327        }
13328    }
13329
13330    public IBinder peekService(Intent service, String resolvedType) {
13331        enforceNotIsolatedCaller("peekService");
13332        // Refuse possible leaked file descriptors
13333        if (service != null && service.hasFileDescriptors() == true) {
13334            throw new IllegalArgumentException("File descriptors passed in Intent");
13335        }
13336        synchronized(this) {
13337            return mServices.peekServiceLocked(service, resolvedType);
13338        }
13339    }
13340
13341    public boolean stopServiceToken(ComponentName className, IBinder token,
13342            int startId) {
13343        synchronized(this) {
13344            return mServices.stopServiceTokenLocked(className, token, startId);
13345        }
13346    }
13347
13348    public void setServiceForeground(ComponentName className, IBinder token,
13349            int id, Notification notification, boolean removeNotification) {
13350        synchronized(this) {
13351            mServices.setServiceForegroundLocked(className, token, id, notification,
13352                    removeNotification);
13353        }
13354    }
13355
13356    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13357            boolean requireFull, String name, String callerPackage) {
13358        final int callingUserId = UserHandle.getUserId(callingUid);
13359        if (callingUserId != userId) {
13360            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13361                if ((requireFull || checkComponentPermission(
13362                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13363                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
13364                        && checkComponentPermission(INTERACT_ACROSS_USERS_FULL,
13365                                callingPid, callingUid, -1, true)
13366                                != PackageManager.PERMISSION_GRANTED) {
13367                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13368                        // In this case, they would like to just execute as their
13369                        // owner user instead of failing.
13370                        userId = callingUserId;
13371                    } else {
13372                        StringBuilder builder = new StringBuilder(128);
13373                        builder.append("Permission Denial: ");
13374                        builder.append(name);
13375                        if (callerPackage != null) {
13376                            builder.append(" from ");
13377                            builder.append(callerPackage);
13378                        }
13379                        builder.append(" asks to run as user ");
13380                        builder.append(userId);
13381                        builder.append(" but is calling from user ");
13382                        builder.append(UserHandle.getUserId(callingUid));
13383                        builder.append("; this requires ");
13384                        builder.append(INTERACT_ACROSS_USERS_FULL);
13385                        if (!requireFull) {
13386                            builder.append(" or ");
13387                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
13388                        }
13389                        String msg = builder.toString();
13390                        Slog.w(TAG, msg);
13391                        throw new SecurityException(msg);
13392                    }
13393                }
13394            }
13395            if (userId == UserHandle.USER_CURRENT
13396                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
13397                // Note that we may be accessing this outside of a lock...
13398                // shouldn't be a big deal, if this is being called outside
13399                // of a locked context there is intrinsically a race with
13400                // the value the caller will receive and someone else changing it.
13401                userId = mCurrentUserId;
13402            }
13403            if (!allowAll && userId < 0) {
13404                throw new IllegalArgumentException(
13405                        "Call does not support special user #" + userId);
13406            }
13407        }
13408        return userId;
13409    }
13410
13411    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13412            String className, int flags) {
13413        boolean result = false;
13414        // For apps that don't have pre-defined UIDs, check for permission
13415        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13416            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13417                if (ActivityManager.checkUidPermission(
13418                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13419                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13420                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13421                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13422                            + " requests FLAG_SINGLE_USER, but app does not hold "
13423                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
13424                    Slog.w(TAG, msg);
13425                    throw new SecurityException(msg);
13426                }
13427                // Permission passed
13428                result = true;
13429            }
13430        } else if ("system".equals(componentProcessName)) {
13431            result = true;
13432        } else {
13433            // App with pre-defined UID, check if it's a persistent app
13434            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13435        }
13436        if (DEBUG_MU) {
13437            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13438                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13439        }
13440        return result;
13441    }
13442
13443    /**
13444     * Checks to see if the caller is in the same app as the singleton
13445     * component, or the component is in a special app. It allows special apps
13446     * to export singleton components but prevents exporting singleton
13447     * components for regular apps.
13448     */
13449    boolean isValidSingletonCall(int callingUid, int componentUid) {
13450        int componentAppId = UserHandle.getAppId(componentUid);
13451        return UserHandle.isSameApp(callingUid, componentUid)
13452                || componentAppId == Process.SYSTEM_UID
13453                || componentAppId == Process.PHONE_UID
13454                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13455                        == PackageManager.PERMISSION_GRANTED;
13456    }
13457
13458    public int bindService(IApplicationThread caller, IBinder token,
13459            Intent service, String resolvedType,
13460            IServiceConnection connection, int flags, int userId) {
13461        enforceNotIsolatedCaller("bindService");
13462        // Refuse possible leaked file descriptors
13463        if (service != null && service.hasFileDescriptors() == true) {
13464            throw new IllegalArgumentException("File descriptors passed in Intent");
13465        }
13466
13467        synchronized(this) {
13468            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13469                    connection, flags, userId);
13470        }
13471    }
13472
13473    public boolean unbindService(IServiceConnection connection) {
13474        synchronized (this) {
13475            return mServices.unbindServiceLocked(connection);
13476        }
13477    }
13478
13479    public void publishService(IBinder token, Intent intent, IBinder service) {
13480        // Refuse possible leaked file descriptors
13481        if (intent != null && intent.hasFileDescriptors() == true) {
13482            throw new IllegalArgumentException("File descriptors passed in Intent");
13483        }
13484
13485        synchronized(this) {
13486            if (!(token instanceof ServiceRecord)) {
13487                throw new IllegalArgumentException("Invalid service token");
13488            }
13489            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13490        }
13491    }
13492
13493    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13494        // Refuse possible leaked file descriptors
13495        if (intent != null && intent.hasFileDescriptors() == true) {
13496            throw new IllegalArgumentException("File descriptors passed in Intent");
13497        }
13498
13499        synchronized(this) {
13500            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13501        }
13502    }
13503
13504    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13505        synchronized(this) {
13506            if (!(token instanceof ServiceRecord)) {
13507                throw new IllegalArgumentException("Invalid service token");
13508            }
13509            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13510        }
13511    }
13512
13513    // =========================================================
13514    // BACKUP AND RESTORE
13515    // =========================================================
13516
13517    // Cause the target app to be launched if necessary and its backup agent
13518    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13519    // activity manager to announce its creation.
13520    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13521        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13522        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
13523
13524        synchronized(this) {
13525            // !!! TODO: currently no check here that we're already bound
13526            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13527            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13528            synchronized (stats) {
13529                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13530            }
13531
13532            // Backup agent is now in use, its package can't be stopped.
13533            try {
13534                AppGlobals.getPackageManager().setPackageStoppedState(
13535                        app.packageName, false, UserHandle.getUserId(app.uid));
13536            } catch (RemoteException e) {
13537            } catch (IllegalArgumentException e) {
13538                Slog.w(TAG, "Failed trying to unstop package "
13539                        + app.packageName + ": " + e);
13540            }
13541
13542            BackupRecord r = new BackupRecord(ss, app, backupMode);
13543            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13544                    ? new ComponentName(app.packageName, app.backupAgentName)
13545                    : new ComponentName("android", "FullBackupAgent");
13546            // startProcessLocked() returns existing proc's record if it's already running
13547            ProcessRecord proc = startProcessLocked(app.processName, app,
13548                    false, 0, "backup", hostingName, false, false, false);
13549            if (proc == null) {
13550                Slog.e(TAG, "Unable to start backup agent process " + r);
13551                return false;
13552            }
13553
13554            r.app = proc;
13555            mBackupTarget = r;
13556            mBackupAppName = app.packageName;
13557
13558            // Try not to kill the process during backup
13559            updateOomAdjLocked(proc);
13560
13561            // If the process is already attached, schedule the creation of the backup agent now.
13562            // If it is not yet live, this will be done when it attaches to the framework.
13563            if (proc.thread != null) {
13564                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13565                try {
13566                    proc.thread.scheduleCreateBackupAgent(app,
13567                            compatibilityInfoForPackageLocked(app), backupMode);
13568                } catch (RemoteException e) {
13569                    // Will time out on the backup manager side
13570                }
13571            } else {
13572                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13573            }
13574            // Invariants: at this point, the target app process exists and the application
13575            // is either already running or in the process of coming up.  mBackupTarget and
13576            // mBackupAppName describe the app, so that when it binds back to the AM we
13577            // know that it's scheduled for a backup-agent operation.
13578        }
13579
13580        return true;
13581    }
13582
13583    @Override
13584    public void clearPendingBackup() {
13585        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13586        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13587
13588        synchronized (this) {
13589            mBackupTarget = null;
13590            mBackupAppName = null;
13591        }
13592    }
13593
13594    // A backup agent has just come up
13595    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13596        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13597                + " = " + agent);
13598
13599        synchronized(this) {
13600            if (!agentPackageName.equals(mBackupAppName)) {
13601                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13602                return;
13603            }
13604        }
13605
13606        long oldIdent = Binder.clearCallingIdentity();
13607        try {
13608            IBackupManager bm = IBackupManager.Stub.asInterface(
13609                    ServiceManager.getService(Context.BACKUP_SERVICE));
13610            bm.agentConnected(agentPackageName, agent);
13611        } catch (RemoteException e) {
13612            // can't happen; the backup manager service is local
13613        } catch (Exception e) {
13614            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13615            e.printStackTrace();
13616        } finally {
13617            Binder.restoreCallingIdentity(oldIdent);
13618        }
13619    }
13620
13621    // done with this agent
13622    public void unbindBackupAgent(ApplicationInfo appInfo) {
13623        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13624        if (appInfo == null) {
13625            Slog.w(TAG, "unbind backup agent for null app");
13626            return;
13627        }
13628
13629        synchronized(this) {
13630            try {
13631                if (mBackupAppName == null) {
13632                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13633                    return;
13634                }
13635
13636                if (!mBackupAppName.equals(appInfo.packageName)) {
13637                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13638                    return;
13639                }
13640
13641                // Not backing this app up any more; reset its OOM adjustment
13642                final ProcessRecord proc = mBackupTarget.app;
13643                updateOomAdjLocked(proc);
13644
13645                // If the app crashed during backup, 'thread' will be null here
13646                if (proc.thread != null) {
13647                    try {
13648                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13649                                compatibilityInfoForPackageLocked(appInfo));
13650                    } catch (Exception e) {
13651                        Slog.e(TAG, "Exception when unbinding backup agent:");
13652                        e.printStackTrace();
13653                    }
13654                }
13655            } finally {
13656                mBackupTarget = null;
13657                mBackupAppName = null;
13658            }
13659        }
13660    }
13661    // =========================================================
13662    // BROADCASTS
13663    // =========================================================
13664
13665    private final List getStickiesLocked(String action, IntentFilter filter,
13666            List cur, int userId) {
13667        final ContentResolver resolver = mContext.getContentResolver();
13668        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13669        if (stickies == null) {
13670            return cur;
13671        }
13672        final ArrayList<Intent> list = stickies.get(action);
13673        if (list == null) {
13674            return cur;
13675        }
13676        int N = list.size();
13677        for (int i=0; i<N; i++) {
13678            Intent intent = list.get(i);
13679            if (filter.match(resolver, intent, true, TAG) >= 0) {
13680                if (cur == null) {
13681                    cur = new ArrayList<Intent>();
13682                }
13683                cur.add(intent);
13684            }
13685        }
13686        return cur;
13687    }
13688
13689    boolean isPendingBroadcastProcessLocked(int pid) {
13690        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13691                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13692    }
13693
13694    void skipPendingBroadcastLocked(int pid) {
13695            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13696            for (BroadcastQueue queue : mBroadcastQueues) {
13697                queue.skipPendingBroadcastLocked(pid);
13698            }
13699    }
13700
13701    // The app just attached; send any pending broadcasts that it should receive
13702    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13703        boolean didSomething = false;
13704        for (BroadcastQueue queue : mBroadcastQueues) {
13705            didSomething |= queue.sendPendingBroadcastsLocked(app);
13706        }
13707        return didSomething;
13708    }
13709
13710    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13711            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13712        enforceNotIsolatedCaller("registerReceiver");
13713        int callingUid;
13714        int callingPid;
13715        synchronized(this) {
13716            ProcessRecord callerApp = null;
13717            if (caller != null) {
13718                callerApp = getRecordForAppLocked(caller);
13719                if (callerApp == null) {
13720                    throw new SecurityException(
13721                            "Unable to find app for caller " + caller
13722                            + " (pid=" + Binder.getCallingPid()
13723                            + ") when registering receiver " + receiver);
13724                }
13725                if (callerApp.info.uid != Process.SYSTEM_UID &&
13726                        !callerApp.pkgList.containsKey(callerPackage) &&
13727                        !"android".equals(callerPackage)) {
13728                    throw new SecurityException("Given caller package " + callerPackage
13729                            + " is not running in process " + callerApp);
13730                }
13731                callingUid = callerApp.info.uid;
13732                callingPid = callerApp.pid;
13733            } else {
13734                callerPackage = null;
13735                callingUid = Binder.getCallingUid();
13736                callingPid = Binder.getCallingPid();
13737            }
13738
13739            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13740                    true, true, "registerReceiver", callerPackage);
13741
13742            List allSticky = null;
13743
13744            // Look for any matching sticky broadcasts...
13745            Iterator actions = filter.actionsIterator();
13746            if (actions != null) {
13747                while (actions.hasNext()) {
13748                    String action = (String)actions.next();
13749                    allSticky = getStickiesLocked(action, filter, allSticky,
13750                            UserHandle.USER_ALL);
13751                    allSticky = getStickiesLocked(action, filter, allSticky,
13752                            UserHandle.getUserId(callingUid));
13753                }
13754            } else {
13755                allSticky = getStickiesLocked(null, filter, allSticky,
13756                        UserHandle.USER_ALL);
13757                allSticky = getStickiesLocked(null, filter, allSticky,
13758                        UserHandle.getUserId(callingUid));
13759            }
13760
13761            // The first sticky in the list is returned directly back to
13762            // the client.
13763            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13764
13765            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13766                    + ": " + sticky);
13767
13768            if (receiver == null) {
13769                return sticky;
13770            }
13771
13772            ReceiverList rl
13773                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13774            if (rl == null) {
13775                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13776                        userId, receiver);
13777                if (rl.app != null) {
13778                    rl.app.receivers.add(rl);
13779                } else {
13780                    try {
13781                        receiver.asBinder().linkToDeath(rl, 0);
13782                    } catch (RemoteException e) {
13783                        return sticky;
13784                    }
13785                    rl.linkedToDeath = true;
13786                }
13787                mRegisteredReceivers.put(receiver.asBinder(), rl);
13788            } else if (rl.uid != callingUid) {
13789                throw new IllegalArgumentException(
13790                        "Receiver requested to register for uid " + callingUid
13791                        + " was previously registered for uid " + rl.uid);
13792            } else if (rl.pid != callingPid) {
13793                throw new IllegalArgumentException(
13794                        "Receiver requested to register for pid " + callingPid
13795                        + " was previously registered for pid " + rl.pid);
13796            } else if (rl.userId != userId) {
13797                throw new IllegalArgumentException(
13798                        "Receiver requested to register for user " + userId
13799                        + " was previously registered for user " + rl.userId);
13800            }
13801            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13802                    permission, callingUid, userId);
13803            rl.add(bf);
13804            if (!bf.debugCheck()) {
13805                Slog.w(TAG, "==> For Dynamic broadast");
13806            }
13807            mReceiverResolver.addFilter(bf);
13808
13809            // Enqueue broadcasts for all existing stickies that match
13810            // this filter.
13811            if (allSticky != null) {
13812                ArrayList receivers = new ArrayList();
13813                receivers.add(bf);
13814
13815                int N = allSticky.size();
13816                for (int i=0; i<N; i++) {
13817                    Intent intent = (Intent)allSticky.get(i);
13818                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13819                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13820                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13821                            null, null, false, true, true, -1);
13822                    queue.enqueueParallelBroadcastLocked(r);
13823                    queue.scheduleBroadcastsLocked();
13824                }
13825            }
13826
13827            return sticky;
13828        }
13829    }
13830
13831    public void unregisterReceiver(IIntentReceiver receiver) {
13832        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13833
13834        final long origId = Binder.clearCallingIdentity();
13835        try {
13836            boolean doTrim = false;
13837
13838            synchronized(this) {
13839                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13840                if (rl != null) {
13841                    if (rl.curBroadcast != null) {
13842                        BroadcastRecord r = rl.curBroadcast;
13843                        final boolean doNext = finishReceiverLocked(
13844                                receiver.asBinder(), r.resultCode, r.resultData,
13845                                r.resultExtras, r.resultAbort);
13846                        if (doNext) {
13847                            doTrim = true;
13848                            r.queue.processNextBroadcast(false);
13849                        }
13850                    }
13851
13852                    if (rl.app != null) {
13853                        rl.app.receivers.remove(rl);
13854                    }
13855                    removeReceiverLocked(rl);
13856                    if (rl.linkedToDeath) {
13857                        rl.linkedToDeath = false;
13858                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13859                    }
13860                }
13861            }
13862
13863            // If we actually concluded any broadcasts, we might now be able
13864            // to trim the recipients' apps from our working set
13865            if (doTrim) {
13866                trimApplications();
13867                return;
13868            }
13869
13870        } finally {
13871            Binder.restoreCallingIdentity(origId);
13872        }
13873    }
13874
13875    void removeReceiverLocked(ReceiverList rl) {
13876        mRegisteredReceivers.remove(rl.receiver.asBinder());
13877        int N = rl.size();
13878        for (int i=0; i<N; i++) {
13879            mReceiverResolver.removeFilter(rl.get(i));
13880        }
13881    }
13882
13883    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13884        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13885            ProcessRecord r = mLruProcesses.get(i);
13886            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13887                try {
13888                    r.thread.dispatchPackageBroadcast(cmd, packages);
13889                } catch (RemoteException ex) {
13890                }
13891            }
13892        }
13893    }
13894
13895    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13896            int[] users) {
13897        List<ResolveInfo> receivers = null;
13898        try {
13899            HashSet<ComponentName> singleUserReceivers = null;
13900            boolean scannedFirstReceivers = false;
13901            for (int user : users) {
13902                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13903                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13904                if (user != 0 && newReceivers != null) {
13905                    // If this is not the primary user, we need to check for
13906                    // any receivers that should be filtered out.
13907                    for (int i=0; i<newReceivers.size(); i++) {
13908                        ResolveInfo ri = newReceivers.get(i);
13909                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13910                            newReceivers.remove(i);
13911                            i--;
13912                        }
13913                    }
13914                }
13915                if (newReceivers != null && newReceivers.size() == 0) {
13916                    newReceivers = null;
13917                }
13918                if (receivers == null) {
13919                    receivers = newReceivers;
13920                } else if (newReceivers != null) {
13921                    // We need to concatenate the additional receivers
13922                    // found with what we have do far.  This would be easy,
13923                    // but we also need to de-dup any receivers that are
13924                    // singleUser.
13925                    if (!scannedFirstReceivers) {
13926                        // Collect any single user receivers we had already retrieved.
13927                        scannedFirstReceivers = true;
13928                        for (int i=0; i<receivers.size(); i++) {
13929                            ResolveInfo ri = receivers.get(i);
13930                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13931                                ComponentName cn = new ComponentName(
13932                                        ri.activityInfo.packageName, ri.activityInfo.name);
13933                                if (singleUserReceivers == null) {
13934                                    singleUserReceivers = new HashSet<ComponentName>();
13935                                }
13936                                singleUserReceivers.add(cn);
13937                            }
13938                        }
13939                    }
13940                    // Add the new results to the existing results, tracking
13941                    // and de-dupping single user receivers.
13942                    for (int i=0; i<newReceivers.size(); i++) {
13943                        ResolveInfo ri = newReceivers.get(i);
13944                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13945                            ComponentName cn = new ComponentName(
13946                                    ri.activityInfo.packageName, ri.activityInfo.name);
13947                            if (singleUserReceivers == null) {
13948                                singleUserReceivers = new HashSet<ComponentName>();
13949                            }
13950                            if (!singleUserReceivers.contains(cn)) {
13951                                singleUserReceivers.add(cn);
13952                                receivers.add(ri);
13953                            }
13954                        } else {
13955                            receivers.add(ri);
13956                        }
13957                    }
13958                }
13959            }
13960        } catch (RemoteException ex) {
13961            // pm is in same process, this will never happen.
13962        }
13963        return receivers;
13964    }
13965
13966    private final int broadcastIntentLocked(ProcessRecord callerApp,
13967            String callerPackage, Intent intent, String resolvedType,
13968            IIntentReceiver resultTo, int resultCode, String resultData,
13969            Bundle map, String requiredPermission, int appOp,
13970            boolean ordered, boolean sticky, int callingPid, int callingUid,
13971            int userId) {
13972        intent = new Intent(intent);
13973
13974        // By default broadcasts do not go to stopped apps.
13975        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13976
13977        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13978            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13979            + " ordered=" + ordered + " userid=" + userId);
13980        if ((resultTo != null) && !ordered) {
13981            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13982        }
13983
13984        userId = handleIncomingUser(callingPid, callingUid, userId,
13985                true, false, "broadcast", callerPackage);
13986
13987        // Make sure that the user who is receiving this broadcast is started.
13988        // If not, we will just skip it.
13989
13990
13991        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13992            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13993                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13994                Slog.w(TAG, "Skipping broadcast of " + intent
13995                        + ": user " + userId + " is stopped");
13996                return ActivityManager.BROADCAST_SUCCESS;
13997            }
13998        }
13999
14000        /*
14001         * Prevent non-system code (defined here to be non-persistent
14002         * processes) from sending protected broadcasts.
14003         */
14004        int callingAppId = UserHandle.getAppId(callingUid);
14005        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
14006            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
14007            || callingAppId == Process.NFC_UID || callingUid == 0) {
14008            // Always okay.
14009        } else if (callerApp == null || !callerApp.persistent) {
14010            try {
14011                if (AppGlobals.getPackageManager().isProtectedBroadcast(
14012                        intent.getAction())) {
14013                    String msg = "Permission Denial: not allowed to send broadcast "
14014                            + intent.getAction() + " from pid="
14015                            + callingPid + ", uid=" + callingUid;
14016                    Slog.w(TAG, msg);
14017                    throw new SecurityException(msg);
14018                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
14019                    // Special case for compatibility: we don't want apps to send this,
14020                    // but historically it has not been protected and apps may be using it
14021                    // to poke their own app widget.  So, instead of making it protected,
14022                    // just limit it to the caller.
14023                    if (callerApp == null) {
14024                        String msg = "Permission Denial: not allowed to send broadcast "
14025                                + intent.getAction() + " from unknown caller.";
14026                        Slog.w(TAG, msg);
14027                        throw new SecurityException(msg);
14028                    } else if (intent.getComponent() != null) {
14029                        // They are good enough to send to an explicit component...  verify
14030                        // it is being sent to the calling app.
14031                        if (!intent.getComponent().getPackageName().equals(
14032                                callerApp.info.packageName)) {
14033                            String msg = "Permission Denial: not allowed to send broadcast "
14034                                    + intent.getAction() + " to "
14035                                    + intent.getComponent().getPackageName() + " from "
14036                                    + callerApp.info.packageName;
14037                            Slog.w(TAG, msg);
14038                            throw new SecurityException(msg);
14039                        }
14040                    } else {
14041                        // Limit broadcast to their own package.
14042                        intent.setPackage(callerApp.info.packageName);
14043                    }
14044                }
14045            } catch (RemoteException e) {
14046                Slog.w(TAG, "Remote exception", e);
14047                return ActivityManager.BROADCAST_SUCCESS;
14048            }
14049        }
14050
14051        // Handle special intents: if this broadcast is from the package
14052        // manager about a package being removed, we need to remove all of
14053        // its activities from the history stack.
14054        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14055                intent.getAction());
14056        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14057                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14058                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14059                || uidRemoved) {
14060            if (checkComponentPermission(
14061                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14062                    callingPid, callingUid, -1, true)
14063                    == PackageManager.PERMISSION_GRANTED) {
14064                if (uidRemoved) {
14065                    final Bundle intentExtras = intent.getExtras();
14066                    final int uid = intentExtras != null
14067                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14068                    if (uid >= 0) {
14069                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14070                        synchronized (bs) {
14071                            bs.removeUidStatsLocked(uid);
14072                        }
14073                        mAppOpsService.uidRemoved(uid);
14074                    }
14075                } else {
14076                    // If resources are unavailable just force stop all
14077                    // those packages and flush the attribute cache as well.
14078                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14079                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14080                        if (list != null && (list.length > 0)) {
14081                            for (String pkg : list) {
14082                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14083                                        "storage unmount");
14084                            }
14085                            sendPackageBroadcastLocked(
14086                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14087                        }
14088                    } else {
14089                        Uri data = intent.getData();
14090                        String ssp;
14091                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14092                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14093                                    intent.getAction());
14094                            boolean fullUninstall = removed &&
14095                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14096                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14097                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14098                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14099                                        false, fullUninstall, userId,
14100                                        removed ? "pkg removed" : "pkg changed");
14101                            }
14102                            if (removed) {
14103                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14104                                        new String[] {ssp}, userId);
14105                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14106                                    mAppOpsService.packageRemoved(
14107                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14108
14109                                    // Remove all permissions granted from/to this package
14110                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14111                                }
14112                            }
14113                        }
14114                    }
14115                }
14116            } else {
14117                String msg = "Permission Denial: " + intent.getAction()
14118                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14119                        + ", uid=" + callingUid + ")"
14120                        + " requires "
14121                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14122                Slog.w(TAG, msg);
14123                throw new SecurityException(msg);
14124            }
14125
14126        // Special case for adding a package: by default turn on compatibility
14127        // mode.
14128        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14129            Uri data = intent.getData();
14130            String ssp;
14131            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14132                mCompatModePackages.handlePackageAddedLocked(ssp,
14133                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14134            }
14135        }
14136
14137        /*
14138         * If this is the time zone changed action, queue up a message that will reset the timezone
14139         * of all currently running processes. This message will get queued up before the broadcast
14140         * happens.
14141         */
14142        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14143            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14144        }
14145
14146        /*
14147         * If the user set the time, let all running processes know.
14148         */
14149        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14150            final int is24Hour = intent.getBooleanExtra(
14151                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14152            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14153        }
14154
14155        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14156            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14157        }
14158
14159        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14160            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14161            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14162        }
14163
14164        // Add to the sticky list if requested.
14165        if (sticky) {
14166            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14167                    callingPid, callingUid)
14168                    != PackageManager.PERMISSION_GRANTED) {
14169                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14170                        + callingPid + ", uid=" + callingUid
14171                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14172                Slog.w(TAG, msg);
14173                throw new SecurityException(msg);
14174            }
14175            if (requiredPermission != null) {
14176                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14177                        + " and enforce permission " + requiredPermission);
14178                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14179            }
14180            if (intent.getComponent() != null) {
14181                throw new SecurityException(
14182                        "Sticky broadcasts can't target a specific component");
14183            }
14184            // We use userId directly here, since the "all" target is maintained
14185            // as a separate set of sticky broadcasts.
14186            if (userId != UserHandle.USER_ALL) {
14187                // But first, if this is not a broadcast to all users, then
14188                // make sure it doesn't conflict with an existing broadcast to
14189                // all users.
14190                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14191                        UserHandle.USER_ALL);
14192                if (stickies != null) {
14193                    ArrayList<Intent> list = stickies.get(intent.getAction());
14194                    if (list != null) {
14195                        int N = list.size();
14196                        int i;
14197                        for (i=0; i<N; i++) {
14198                            if (intent.filterEquals(list.get(i))) {
14199                                throw new IllegalArgumentException(
14200                                        "Sticky broadcast " + intent + " for user "
14201                                        + userId + " conflicts with existing global broadcast");
14202                            }
14203                        }
14204                    }
14205                }
14206            }
14207            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14208            if (stickies == null) {
14209                stickies = new ArrayMap<String, ArrayList<Intent>>();
14210                mStickyBroadcasts.put(userId, stickies);
14211            }
14212            ArrayList<Intent> list = stickies.get(intent.getAction());
14213            if (list == null) {
14214                list = new ArrayList<Intent>();
14215                stickies.put(intent.getAction(), list);
14216            }
14217            int N = list.size();
14218            int i;
14219            for (i=0; i<N; i++) {
14220                if (intent.filterEquals(list.get(i))) {
14221                    // This sticky already exists, replace it.
14222                    list.set(i, new Intent(intent));
14223                    break;
14224                }
14225            }
14226            if (i >= N) {
14227                list.add(new Intent(intent));
14228            }
14229        }
14230
14231        int[] users;
14232        if (userId == UserHandle.USER_ALL) {
14233            // Caller wants broadcast to go to all started users.
14234            users = mStartedUserArray;
14235        } else {
14236            // Caller wants broadcast to go to one specific user.
14237            users = new int[] {userId};
14238        }
14239
14240        // Figure out who all will receive this broadcast.
14241        List receivers = null;
14242        List<BroadcastFilter> registeredReceivers = null;
14243        // Need to resolve the intent to interested receivers...
14244        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14245                 == 0) {
14246            receivers = collectReceiverComponents(intent, resolvedType, users);
14247        }
14248        if (intent.getComponent() == null) {
14249            registeredReceivers = mReceiverResolver.queryIntent(intent,
14250                    resolvedType, false, userId);
14251        }
14252
14253        final boolean replacePending =
14254                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14255
14256        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14257                + " replacePending=" + replacePending);
14258
14259        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14260        if (!ordered && NR > 0) {
14261            // If we are not serializing this broadcast, then send the
14262            // registered receivers separately so they don't wait for the
14263            // components to be launched.
14264            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14265            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14266                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14267                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14268                    ordered, sticky, false, userId);
14269            if (DEBUG_BROADCAST) Slog.v(
14270                    TAG, "Enqueueing parallel broadcast " + r);
14271            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14272            if (!replaced) {
14273                queue.enqueueParallelBroadcastLocked(r);
14274                queue.scheduleBroadcastsLocked();
14275            }
14276            registeredReceivers = null;
14277            NR = 0;
14278        }
14279
14280        // Merge into one list.
14281        int ir = 0;
14282        if (receivers != null) {
14283            // A special case for PACKAGE_ADDED: do not allow the package
14284            // being added to see this broadcast.  This prevents them from
14285            // using this as a back door to get run as soon as they are
14286            // installed.  Maybe in the future we want to have a special install
14287            // broadcast or such for apps, but we'd like to deliberately make
14288            // this decision.
14289            String skipPackages[] = null;
14290            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14291                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14292                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14293                Uri data = intent.getData();
14294                if (data != null) {
14295                    String pkgName = data.getSchemeSpecificPart();
14296                    if (pkgName != null) {
14297                        skipPackages = new String[] { pkgName };
14298                    }
14299                }
14300            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14301                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14302            }
14303            if (skipPackages != null && (skipPackages.length > 0)) {
14304                for (String skipPackage : skipPackages) {
14305                    if (skipPackage != null) {
14306                        int NT = receivers.size();
14307                        for (int it=0; it<NT; it++) {
14308                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14309                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14310                                receivers.remove(it);
14311                                it--;
14312                                NT--;
14313                            }
14314                        }
14315                    }
14316                }
14317            }
14318
14319            int NT = receivers != null ? receivers.size() : 0;
14320            int it = 0;
14321            ResolveInfo curt = null;
14322            BroadcastFilter curr = null;
14323            while (it < NT && ir < NR) {
14324                if (curt == null) {
14325                    curt = (ResolveInfo)receivers.get(it);
14326                }
14327                if (curr == null) {
14328                    curr = registeredReceivers.get(ir);
14329                }
14330                if (curr.getPriority() >= curt.priority) {
14331                    // Insert this broadcast record into the final list.
14332                    receivers.add(it, curr);
14333                    ir++;
14334                    curr = null;
14335                    it++;
14336                    NT++;
14337                } else {
14338                    // Skip to the next ResolveInfo in the final list.
14339                    it++;
14340                    curt = null;
14341                }
14342            }
14343        }
14344        while (ir < NR) {
14345            if (receivers == null) {
14346                receivers = new ArrayList();
14347            }
14348            receivers.add(registeredReceivers.get(ir));
14349            ir++;
14350        }
14351
14352        if ((receivers != null && receivers.size() > 0)
14353                || resultTo != null) {
14354            BroadcastQueue queue = broadcastQueueForIntent(intent);
14355            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14356                    callerPackage, callingPid, callingUid, resolvedType,
14357                    requiredPermission, appOp, receivers, resultTo, resultCode,
14358                    resultData, map, ordered, sticky, false, userId);
14359            if (DEBUG_BROADCAST) Slog.v(
14360                    TAG, "Enqueueing ordered broadcast " + r
14361                    + ": prev had " + queue.mOrderedBroadcasts.size());
14362            if (DEBUG_BROADCAST) {
14363                int seq = r.intent.getIntExtra("seq", -1);
14364                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14365            }
14366            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14367            if (!replaced) {
14368                queue.enqueueOrderedBroadcastLocked(r);
14369                queue.scheduleBroadcastsLocked();
14370            }
14371        }
14372
14373        return ActivityManager.BROADCAST_SUCCESS;
14374    }
14375
14376    final Intent verifyBroadcastLocked(Intent intent) {
14377        // Refuse possible leaked file descriptors
14378        if (intent != null && intent.hasFileDescriptors() == true) {
14379            throw new IllegalArgumentException("File descriptors passed in Intent");
14380        }
14381
14382        int flags = intent.getFlags();
14383
14384        if (!mProcessesReady) {
14385            // if the caller really truly claims to know what they're doing, go
14386            // ahead and allow the broadcast without launching any receivers
14387            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14388                intent = new Intent(intent);
14389                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14390            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14391                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14392                        + " before boot completion");
14393                throw new IllegalStateException("Cannot broadcast before boot completed");
14394            }
14395        }
14396
14397        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14398            throw new IllegalArgumentException(
14399                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14400        }
14401
14402        return intent;
14403    }
14404
14405    public final int broadcastIntent(IApplicationThread caller,
14406            Intent intent, String resolvedType, IIntentReceiver resultTo,
14407            int resultCode, String resultData, Bundle map,
14408            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14409        enforceNotIsolatedCaller("broadcastIntent");
14410        synchronized(this) {
14411            intent = verifyBroadcastLocked(intent);
14412
14413            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14414            final int callingPid = Binder.getCallingPid();
14415            final int callingUid = Binder.getCallingUid();
14416            final long origId = Binder.clearCallingIdentity();
14417            int res = broadcastIntentLocked(callerApp,
14418                    callerApp != null ? callerApp.info.packageName : null,
14419                    intent, resolvedType, resultTo,
14420                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14421                    callingPid, callingUid, userId);
14422            Binder.restoreCallingIdentity(origId);
14423            return res;
14424        }
14425    }
14426
14427    int broadcastIntentInPackage(String packageName, int uid,
14428            Intent intent, String resolvedType, IIntentReceiver resultTo,
14429            int resultCode, String resultData, Bundle map,
14430            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14431        synchronized(this) {
14432            intent = verifyBroadcastLocked(intent);
14433
14434            final long origId = Binder.clearCallingIdentity();
14435            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14436                    resultTo, resultCode, resultData, map, requiredPermission,
14437                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14438            Binder.restoreCallingIdentity(origId);
14439            return res;
14440        }
14441    }
14442
14443    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14444        // Refuse possible leaked file descriptors
14445        if (intent != null && intent.hasFileDescriptors() == true) {
14446            throw new IllegalArgumentException("File descriptors passed in Intent");
14447        }
14448
14449        userId = handleIncomingUser(Binder.getCallingPid(),
14450                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
14451
14452        synchronized(this) {
14453            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14454                    != PackageManager.PERMISSION_GRANTED) {
14455                String msg = "Permission Denial: unbroadcastIntent() from pid="
14456                        + Binder.getCallingPid()
14457                        + ", uid=" + Binder.getCallingUid()
14458                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14459                Slog.w(TAG, msg);
14460                throw new SecurityException(msg);
14461            }
14462            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14463            if (stickies != null) {
14464                ArrayList<Intent> list = stickies.get(intent.getAction());
14465                if (list != null) {
14466                    int N = list.size();
14467                    int i;
14468                    for (i=0; i<N; i++) {
14469                        if (intent.filterEquals(list.get(i))) {
14470                            list.remove(i);
14471                            break;
14472                        }
14473                    }
14474                    if (list.size() <= 0) {
14475                        stickies.remove(intent.getAction());
14476                    }
14477                }
14478                if (stickies.size() <= 0) {
14479                    mStickyBroadcasts.remove(userId);
14480                }
14481            }
14482        }
14483    }
14484
14485    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14486            String resultData, Bundle resultExtras, boolean resultAbort) {
14487        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14488        if (r == null) {
14489            Slog.w(TAG, "finishReceiver called but not found on queue");
14490            return false;
14491        }
14492
14493        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14494    }
14495
14496    void backgroundServicesFinishedLocked(int userId) {
14497        for (BroadcastQueue queue : mBroadcastQueues) {
14498            queue.backgroundServicesFinishedLocked(userId);
14499        }
14500    }
14501
14502    public void finishReceiver(IBinder who, int resultCode, String resultData,
14503            Bundle resultExtras, boolean resultAbort) {
14504        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14505
14506        // Refuse possible leaked file descriptors
14507        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14508            throw new IllegalArgumentException("File descriptors passed in Bundle");
14509        }
14510
14511        final long origId = Binder.clearCallingIdentity();
14512        try {
14513            boolean doNext = false;
14514            BroadcastRecord r;
14515
14516            synchronized(this) {
14517                r = broadcastRecordForReceiverLocked(who);
14518                if (r != null) {
14519                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14520                        resultData, resultExtras, resultAbort, true);
14521                }
14522            }
14523
14524            if (doNext) {
14525                r.queue.processNextBroadcast(false);
14526            }
14527            trimApplications();
14528        } finally {
14529            Binder.restoreCallingIdentity(origId);
14530        }
14531    }
14532
14533    // =========================================================
14534    // INSTRUMENTATION
14535    // =========================================================
14536
14537    public boolean startInstrumentation(ComponentName className,
14538            String profileFile, int flags, Bundle arguments,
14539            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14540            int userId, String abiOverride) {
14541        enforceNotIsolatedCaller("startInstrumentation");
14542        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14543                userId, false, true, "startInstrumentation", null);
14544        // Refuse possible leaked file descriptors
14545        if (arguments != null && arguments.hasFileDescriptors()) {
14546            throw new IllegalArgumentException("File descriptors passed in Bundle");
14547        }
14548
14549        synchronized(this) {
14550            InstrumentationInfo ii = null;
14551            ApplicationInfo ai = null;
14552            try {
14553                ii = mContext.getPackageManager().getInstrumentationInfo(
14554                    className, STOCK_PM_FLAGS);
14555                ai = AppGlobals.getPackageManager().getApplicationInfo(
14556                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14557            } catch (PackageManager.NameNotFoundException e) {
14558            } catch (RemoteException e) {
14559            }
14560            if (ii == null) {
14561                reportStartInstrumentationFailure(watcher, className,
14562                        "Unable to find instrumentation info for: " + className);
14563                return false;
14564            }
14565            if (ai == null) {
14566                reportStartInstrumentationFailure(watcher, className,
14567                        "Unable to find instrumentation target package: " + ii.targetPackage);
14568                return false;
14569            }
14570
14571            int match = mContext.getPackageManager().checkSignatures(
14572                    ii.targetPackage, ii.packageName);
14573            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14574                String msg = "Permission Denial: starting instrumentation "
14575                        + className + " from pid="
14576                        + Binder.getCallingPid()
14577                        + ", uid=" + Binder.getCallingPid()
14578                        + " not allowed because package " + ii.packageName
14579                        + " does not have a signature matching the target "
14580                        + ii.targetPackage;
14581                reportStartInstrumentationFailure(watcher, className, msg);
14582                throw new SecurityException(msg);
14583            }
14584
14585            final long origId = Binder.clearCallingIdentity();
14586            // Instrumentation can kill and relaunch even persistent processes
14587            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14588                    "start instr");
14589            ProcessRecord app = addAppLocked(ai, false, abiOverride);
14590            app.instrumentationClass = className;
14591            app.instrumentationInfo = ai;
14592            app.instrumentationProfileFile = profileFile;
14593            app.instrumentationArguments = arguments;
14594            app.instrumentationWatcher = watcher;
14595            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14596            app.instrumentationResultClass = className;
14597            Binder.restoreCallingIdentity(origId);
14598        }
14599
14600        return true;
14601    }
14602
14603    /**
14604     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14605     * error to the logs, but if somebody is watching, send the report there too.  This enables
14606     * the "am" command to report errors with more information.
14607     *
14608     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14609     * @param cn The component name of the instrumentation.
14610     * @param report The error report.
14611     */
14612    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14613            ComponentName cn, String report) {
14614        Slog.w(TAG, report);
14615        try {
14616            if (watcher != null) {
14617                Bundle results = new Bundle();
14618                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14619                results.putString("Error", report);
14620                watcher.instrumentationStatus(cn, -1, results);
14621            }
14622        } catch (RemoteException e) {
14623            Slog.w(TAG, e);
14624        }
14625    }
14626
14627    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14628        if (app.instrumentationWatcher != null) {
14629            try {
14630                // NOTE:  IInstrumentationWatcher *must* be oneway here
14631                app.instrumentationWatcher.instrumentationFinished(
14632                    app.instrumentationClass,
14633                    resultCode,
14634                    results);
14635            } catch (RemoteException e) {
14636            }
14637        }
14638        if (app.instrumentationUiAutomationConnection != null) {
14639            try {
14640                app.instrumentationUiAutomationConnection.shutdown();
14641            } catch (RemoteException re) {
14642                /* ignore */
14643            }
14644            // Only a UiAutomation can set this flag and now that
14645            // it is finished we make sure it is reset to its default.
14646            mUserIsMonkey = false;
14647        }
14648        app.instrumentationWatcher = null;
14649        app.instrumentationUiAutomationConnection = null;
14650        app.instrumentationClass = null;
14651        app.instrumentationInfo = null;
14652        app.instrumentationProfileFile = null;
14653        app.instrumentationArguments = null;
14654
14655        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14656                "finished inst");
14657    }
14658
14659    public void finishInstrumentation(IApplicationThread target,
14660            int resultCode, Bundle results) {
14661        int userId = UserHandle.getCallingUserId();
14662        // Refuse possible leaked file descriptors
14663        if (results != null && results.hasFileDescriptors()) {
14664            throw new IllegalArgumentException("File descriptors passed in Intent");
14665        }
14666
14667        synchronized(this) {
14668            ProcessRecord app = getRecordForAppLocked(target);
14669            if (app == null) {
14670                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14671                return;
14672            }
14673            final long origId = Binder.clearCallingIdentity();
14674            finishInstrumentationLocked(app, resultCode, results);
14675            Binder.restoreCallingIdentity(origId);
14676        }
14677    }
14678
14679    // =========================================================
14680    // CONFIGURATION
14681    // =========================================================
14682
14683    public ConfigurationInfo getDeviceConfigurationInfo() {
14684        ConfigurationInfo config = new ConfigurationInfo();
14685        synchronized (this) {
14686            config.reqTouchScreen = mConfiguration.touchscreen;
14687            config.reqKeyboardType = mConfiguration.keyboard;
14688            config.reqNavigation = mConfiguration.navigation;
14689            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14690                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14691                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14692            }
14693            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14694                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14695                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14696            }
14697            config.reqGlEsVersion = GL_ES_VERSION;
14698        }
14699        return config;
14700    }
14701
14702    ActivityStack getFocusedStack() {
14703        return mStackSupervisor.getFocusedStack();
14704    }
14705
14706    public Configuration getConfiguration() {
14707        Configuration ci;
14708        synchronized(this) {
14709            ci = new Configuration(mConfiguration);
14710        }
14711        return ci;
14712    }
14713
14714    public void updatePersistentConfiguration(Configuration values) {
14715        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14716                "updateConfiguration()");
14717        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14718                "updateConfiguration()");
14719        if (values == null) {
14720            throw new NullPointerException("Configuration must not be null");
14721        }
14722
14723        synchronized(this) {
14724            final long origId = Binder.clearCallingIdentity();
14725            updateConfigurationLocked(values, null, true, false);
14726            Binder.restoreCallingIdentity(origId);
14727        }
14728    }
14729
14730    public void updateConfiguration(Configuration values) {
14731        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14732                "updateConfiguration()");
14733
14734        synchronized(this) {
14735            if (values == null && mWindowManager != null) {
14736                // sentinel: fetch the current configuration from the window manager
14737                values = mWindowManager.computeNewConfiguration();
14738            }
14739
14740            if (mWindowManager != null) {
14741                mProcessList.applyDisplaySize(mWindowManager);
14742            }
14743
14744            final long origId = Binder.clearCallingIdentity();
14745            if (values != null) {
14746                Settings.System.clearConfiguration(values);
14747            }
14748            updateConfigurationLocked(values, null, false, false);
14749            Binder.restoreCallingIdentity(origId);
14750        }
14751    }
14752
14753    /**
14754     * Do either or both things: (1) change the current configuration, and (2)
14755     * make sure the given activity is running with the (now) current
14756     * configuration.  Returns true if the activity has been left running, or
14757     * false if <var>starting</var> is being destroyed to match the new
14758     * configuration.
14759     * @param persistent TODO
14760     */
14761    boolean updateConfigurationLocked(Configuration values,
14762            ActivityRecord starting, boolean persistent, boolean initLocale) {
14763        int changes = 0;
14764
14765        if (values != null) {
14766            Configuration newConfig = new Configuration(mConfiguration);
14767            changes = newConfig.updateFrom(values);
14768            if (changes != 0) {
14769                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14770                    Slog.i(TAG, "Updating configuration to: " + values);
14771                }
14772
14773                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14774
14775                if (values.locale != null && !initLocale) {
14776                    saveLocaleLocked(values.locale,
14777                                     !values.locale.equals(mConfiguration.locale),
14778                                     values.userSetLocale);
14779                }
14780
14781                mConfigurationSeq++;
14782                if (mConfigurationSeq <= 0) {
14783                    mConfigurationSeq = 1;
14784                }
14785                newConfig.seq = mConfigurationSeq;
14786                mConfiguration = newConfig;
14787                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14788                mUsageStatsService.noteStartConfig(newConfig);
14789
14790                final Configuration configCopy = new Configuration(mConfiguration);
14791
14792                // TODO: If our config changes, should we auto dismiss any currently
14793                // showing dialogs?
14794                mShowDialogs = shouldShowDialogs(newConfig);
14795
14796                AttributeCache ac = AttributeCache.instance();
14797                if (ac != null) {
14798                    ac.updateConfiguration(configCopy);
14799                }
14800
14801                // Make sure all resources in our process are updated
14802                // right now, so that anyone who is going to retrieve
14803                // resource values after we return will be sure to get
14804                // the new ones.  This is especially important during
14805                // boot, where the first config change needs to guarantee
14806                // all resources have that config before following boot
14807                // code is executed.
14808                mSystemThread.applyConfigurationToResources(configCopy);
14809
14810                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14811                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14812                    msg.obj = new Configuration(configCopy);
14813                    mHandler.sendMessage(msg);
14814                }
14815
14816                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14817                    ProcessRecord app = mLruProcesses.get(i);
14818                    try {
14819                        if (app.thread != null) {
14820                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14821                                    + app.processName + " new config " + mConfiguration);
14822                            app.thread.scheduleConfigurationChanged(configCopy);
14823                        }
14824                    } catch (Exception e) {
14825                    }
14826                }
14827                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14828                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14829                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14830                        | Intent.FLAG_RECEIVER_FOREGROUND);
14831                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14832                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14833                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14834                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14835                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14836                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14837                    broadcastIntentLocked(null, null, intent,
14838                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14839                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14840                }
14841            }
14842        }
14843
14844        boolean kept = true;
14845        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14846        // mainStack is null during startup.
14847        if (mainStack != null) {
14848            if (changes != 0 && starting == null) {
14849                // If the configuration changed, and the caller is not already
14850                // in the process of starting an activity, then find the top
14851                // activity to check if its configuration needs to change.
14852                starting = mainStack.topRunningActivityLocked(null);
14853            }
14854
14855            if (starting != null) {
14856                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14857                // And we need to make sure at this point that all other activities
14858                // are made visible with the correct configuration.
14859                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14860            }
14861        }
14862
14863        if (values != null && mWindowManager != null) {
14864            mWindowManager.setNewConfiguration(mConfiguration);
14865        }
14866
14867        return kept;
14868    }
14869
14870    /**
14871     * Decide based on the configuration whether we should shouw the ANR,
14872     * crash, etc dialogs.  The idea is that if there is no affordnace to
14873     * press the on-screen buttons, we shouldn't show the dialog.
14874     *
14875     * A thought: SystemUI might also want to get told about this, the Power
14876     * dialog / global actions also might want different behaviors.
14877     */
14878    private static final boolean shouldShowDialogs(Configuration config) {
14879        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14880                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14881    }
14882
14883    /**
14884     * Save the locale.  You must be inside a synchronized (this) block.
14885     */
14886    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14887        if(isDiff) {
14888            SystemProperties.set("user.language", l.getLanguage());
14889            SystemProperties.set("user.region", l.getCountry());
14890        }
14891
14892        if(isPersist) {
14893            SystemProperties.set("persist.sys.language", l.getLanguage());
14894            SystemProperties.set("persist.sys.country", l.getCountry());
14895            SystemProperties.set("persist.sys.localevar", l.getVariant());
14896        }
14897    }
14898
14899    @Override
14900    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14901        ActivityRecord srec = ActivityRecord.forToken(token);
14902        return srec != null && srec.task.affinity != null &&
14903                srec.task.affinity.equals(destAffinity);
14904    }
14905
14906    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14907            Intent resultData) {
14908
14909        synchronized (this) {
14910            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14911            if (stack != null) {
14912                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14913            }
14914            return false;
14915        }
14916    }
14917
14918    public int getLaunchedFromUid(IBinder activityToken) {
14919        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14920        if (srec == null) {
14921            return -1;
14922        }
14923        return srec.launchedFromUid;
14924    }
14925
14926    public String getLaunchedFromPackage(IBinder activityToken) {
14927        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14928        if (srec == null) {
14929            return null;
14930        }
14931        return srec.launchedFromPackage;
14932    }
14933
14934    // =========================================================
14935    // LIFETIME MANAGEMENT
14936    // =========================================================
14937
14938    // Returns which broadcast queue the app is the current [or imminent] receiver
14939    // on, or 'null' if the app is not an active broadcast recipient.
14940    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14941        BroadcastRecord r = app.curReceiver;
14942        if (r != null) {
14943            return r.queue;
14944        }
14945
14946        // It's not the current receiver, but it might be starting up to become one
14947        synchronized (this) {
14948            for (BroadcastQueue queue : mBroadcastQueues) {
14949                r = queue.mPendingBroadcast;
14950                if (r != null && r.curApp == app) {
14951                    // found it; report which queue it's in
14952                    return queue;
14953                }
14954            }
14955        }
14956
14957        return null;
14958    }
14959
14960    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14961            boolean doingAll, long now) {
14962        if (mAdjSeq == app.adjSeq) {
14963            // This adjustment has already been computed.
14964            return app.curRawAdj;
14965        }
14966
14967        if (app.thread == null) {
14968            app.adjSeq = mAdjSeq;
14969            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14970            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14971            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14972        }
14973
14974        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14975        app.adjSource = null;
14976        app.adjTarget = null;
14977        app.empty = false;
14978        app.cached = false;
14979
14980        final int activitiesSize = app.activities.size();
14981
14982        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14983            // The max adjustment doesn't allow this app to be anything
14984            // below foreground, so it is not worth doing work for it.
14985            app.adjType = "fixed";
14986            app.adjSeq = mAdjSeq;
14987            app.curRawAdj = app.maxAdj;
14988            app.foregroundActivities = false;
14989            app.keeping = true;
14990            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14991            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14992            // System processes can do UI, and when they do we want to have
14993            // them trim their memory after the user leaves the UI.  To
14994            // facilitate this, here we need to determine whether or not it
14995            // is currently showing UI.
14996            app.systemNoUi = true;
14997            if (app == TOP_APP) {
14998                app.systemNoUi = false;
14999            } else if (activitiesSize > 0) {
15000                for (int j = 0; j < activitiesSize; j++) {
15001                    final ActivityRecord r = app.activities.get(j);
15002                    if (r.visible) {
15003                        app.systemNoUi = false;
15004                    }
15005                }
15006            }
15007            if (!app.systemNoUi) {
15008                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
15009            }
15010            return (app.curAdj=app.maxAdj);
15011        }
15012
15013        app.keeping = false;
15014        app.systemNoUi = false;
15015
15016        // Determine the importance of the process, starting with most
15017        // important to least, and assign an appropriate OOM adjustment.
15018        int adj;
15019        int schedGroup;
15020        int procState;
15021        boolean foregroundActivities = false;
15022        boolean interesting = false;
15023        BroadcastQueue queue;
15024        if (app == TOP_APP) {
15025            // The last app on the list is the foreground app.
15026            adj = ProcessList.FOREGROUND_APP_ADJ;
15027            schedGroup = Process.THREAD_GROUP_DEFAULT;
15028            app.adjType = "top-activity";
15029            foregroundActivities = true;
15030            interesting = true;
15031            procState = ActivityManager.PROCESS_STATE_TOP;
15032        } else if (app.instrumentationClass != null) {
15033            // Don't want to kill running instrumentation.
15034            adj = ProcessList.FOREGROUND_APP_ADJ;
15035            schedGroup = Process.THREAD_GROUP_DEFAULT;
15036            app.adjType = "instrumentation";
15037            interesting = true;
15038            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15039        } else if ((queue = isReceivingBroadcast(app)) != null) {
15040            // An app that is currently receiving a broadcast also
15041            // counts as being in the foreground for OOM killer purposes.
15042            // It's placed in a sched group based on the nature of the
15043            // broadcast as reflected by which queue it's active in.
15044            adj = ProcessList.FOREGROUND_APP_ADJ;
15045            schedGroup = (queue == mFgBroadcastQueue)
15046                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15047            app.adjType = "broadcast";
15048            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15049        } else if (app.executingServices.size() > 0) {
15050            // An app that is currently executing a service callback also
15051            // counts as being in the foreground.
15052            adj = ProcessList.FOREGROUND_APP_ADJ;
15053            schedGroup = app.execServicesFg ?
15054                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15055            app.adjType = "exec-service";
15056            procState = ActivityManager.PROCESS_STATE_SERVICE;
15057            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15058        } else {
15059            // As far as we know the process is empty.  We may change our mind later.
15060            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15061            // At this point we don't actually know the adjustment.  Use the cached adj
15062            // value that the caller wants us to.
15063            adj = cachedAdj;
15064            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15065            app.cached = true;
15066            app.empty = true;
15067            app.adjType = "cch-empty";
15068        }
15069
15070        // Examine all activities if not already foreground.
15071        if (!foregroundActivities && activitiesSize > 0) {
15072            for (int j = 0; j < activitiesSize; j++) {
15073                final ActivityRecord r = app.activities.get(j);
15074                if (r.app != app) {
15075                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15076                            + app + "?!?");
15077                    continue;
15078                }
15079                if (r.visible) {
15080                    // App has a visible activity; only upgrade adjustment.
15081                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15082                        adj = ProcessList.VISIBLE_APP_ADJ;
15083                        app.adjType = "visible";
15084                    }
15085                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15086                        procState = ActivityManager.PROCESS_STATE_TOP;
15087                    }
15088                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15089                    app.cached = false;
15090                    app.empty = false;
15091                    foregroundActivities = true;
15092                    break;
15093                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15094                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15095                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15096                        app.adjType = "pausing";
15097                    }
15098                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15099                        procState = ActivityManager.PROCESS_STATE_TOP;
15100                    }
15101                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15102                    app.cached = false;
15103                    app.empty = false;
15104                    foregroundActivities = true;
15105                } else if (r.state == ActivityState.STOPPING) {
15106                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15107                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15108                        app.adjType = "stopping";
15109                    }
15110                    // For the process state, we will at this point consider the
15111                    // process to be cached.  It will be cached either as an activity
15112                    // or empty depending on whether the activity is finishing.  We do
15113                    // this so that we can treat the process as cached for purposes of
15114                    // memory trimming (determing current memory level, trim command to
15115                    // send to process) since there can be an arbitrary number of stopping
15116                    // processes and they should soon all go into the cached state.
15117                    if (!r.finishing) {
15118                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15119                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15120                        }
15121                    }
15122                    app.cached = false;
15123                    app.empty = false;
15124                    foregroundActivities = true;
15125                } else {
15126                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15127                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15128                        app.adjType = "cch-act";
15129                    }
15130                }
15131            }
15132        }
15133
15134        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15135            if (app.foregroundServices) {
15136                // The user is aware of this app, so make it visible.
15137                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15138                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15139                app.cached = false;
15140                app.adjType = "fg-service";
15141                schedGroup = Process.THREAD_GROUP_DEFAULT;
15142            } else if (app.forcingToForeground != null) {
15143                // The user is aware of this app, so make it visible.
15144                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15145                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15146                app.cached = false;
15147                app.adjType = "force-fg";
15148                app.adjSource = app.forcingToForeground;
15149                schedGroup = Process.THREAD_GROUP_DEFAULT;
15150            }
15151        }
15152
15153        if (app.foregroundServices) {
15154            interesting = true;
15155        }
15156
15157        if (app == mHeavyWeightProcess) {
15158            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15159                // We don't want to kill the current heavy-weight process.
15160                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15161                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15162                app.cached = false;
15163                app.adjType = "heavy";
15164            }
15165            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15166                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15167            }
15168        }
15169
15170        if (app == mHomeProcess) {
15171            if (adj > ProcessList.HOME_APP_ADJ) {
15172                // This process is hosting what we currently consider to be the
15173                // home app, so we don't want to let it go into the background.
15174                adj = ProcessList.HOME_APP_ADJ;
15175                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15176                app.cached = false;
15177                app.adjType = "home";
15178            }
15179            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15180                procState = ActivityManager.PROCESS_STATE_HOME;
15181            }
15182        }
15183
15184        if (app == mPreviousProcess && app.activities.size() > 0) {
15185            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15186                // This was the previous process that showed UI to the user.
15187                // We want to try to keep it around more aggressively, to give
15188                // a good experience around switching between two apps.
15189                adj = ProcessList.PREVIOUS_APP_ADJ;
15190                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15191                app.cached = false;
15192                app.adjType = "previous";
15193            }
15194            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15195                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15196            }
15197        }
15198
15199        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15200                + " reason=" + app.adjType);
15201
15202        // By default, we use the computed adjustment.  It may be changed if
15203        // there are applications dependent on our services or providers, but
15204        // this gives us a baseline and makes sure we don't get into an
15205        // infinite recursion.
15206        app.adjSeq = mAdjSeq;
15207        app.curRawAdj = adj;
15208        app.hasStartedServices = false;
15209
15210        if (mBackupTarget != null && app == mBackupTarget.app) {
15211            // If possible we want to avoid killing apps while they're being backed up
15212            if (adj > ProcessList.BACKUP_APP_ADJ) {
15213                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15214                adj = ProcessList.BACKUP_APP_ADJ;
15215                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15216                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15217                }
15218                app.adjType = "backup";
15219                app.cached = false;
15220            }
15221            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15222                procState = ActivityManager.PROCESS_STATE_BACKUP;
15223            }
15224        }
15225
15226        boolean mayBeTop = false;
15227
15228        for (int is = app.services.size()-1;
15229                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15230                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15231                        || procState > ActivityManager.PROCESS_STATE_TOP);
15232                is--) {
15233            ServiceRecord s = app.services.valueAt(is);
15234            if (s.startRequested) {
15235                app.hasStartedServices = true;
15236                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15237                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15238                }
15239                if (app.hasShownUi && app != mHomeProcess) {
15240                    // If this process has shown some UI, let it immediately
15241                    // go to the LRU list because it may be pretty heavy with
15242                    // UI stuff.  We'll tag it with a label just to help
15243                    // debug and understand what is going on.
15244                    if (adj > ProcessList.SERVICE_ADJ) {
15245                        app.adjType = "cch-started-ui-services";
15246                    }
15247                } else {
15248                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15249                        // This service has seen some activity within
15250                        // recent memory, so we will keep its process ahead
15251                        // of the background processes.
15252                        if (adj > ProcessList.SERVICE_ADJ) {
15253                            adj = ProcessList.SERVICE_ADJ;
15254                            app.adjType = "started-services";
15255                            app.cached = false;
15256                        }
15257                    }
15258                    // If we have let the service slide into the background
15259                    // state, still have some text describing what it is doing
15260                    // even though the service no longer has an impact.
15261                    if (adj > ProcessList.SERVICE_ADJ) {
15262                        app.adjType = "cch-started-services";
15263                    }
15264                }
15265                // Don't kill this process because it is doing work; it
15266                // has said it is doing work.
15267                app.keeping = true;
15268            }
15269            for (int conni = s.connections.size()-1;
15270                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15271                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15272                            || procState > ActivityManager.PROCESS_STATE_TOP);
15273                    conni--) {
15274                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15275                for (int i = 0;
15276                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15277                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15278                                || procState > ActivityManager.PROCESS_STATE_TOP);
15279                        i++) {
15280                    // XXX should compute this based on the max of
15281                    // all connected clients.
15282                    ConnectionRecord cr = clist.get(i);
15283                    if (cr.binding.client == app) {
15284                        // Binding to ourself is not interesting.
15285                        continue;
15286                    }
15287                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15288                        ProcessRecord client = cr.binding.client;
15289                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15290                                TOP_APP, doingAll, now);
15291                        int clientProcState = client.curProcState;
15292                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15293                            // If the other app is cached for any reason, for purposes here
15294                            // we are going to consider it empty.  The specific cached state
15295                            // doesn't propagate except under certain conditions.
15296                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15297                        }
15298                        String adjType = null;
15299                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15300                            // Not doing bind OOM management, so treat
15301                            // this guy more like a started service.
15302                            if (app.hasShownUi && app != mHomeProcess) {
15303                                // If this process has shown some UI, let it immediately
15304                                // go to the LRU list because it may be pretty heavy with
15305                                // UI stuff.  We'll tag it with a label just to help
15306                                // debug and understand what is going on.
15307                                if (adj > clientAdj) {
15308                                    adjType = "cch-bound-ui-services";
15309                                }
15310                                app.cached = false;
15311                                clientAdj = adj;
15312                                clientProcState = procState;
15313                            } else {
15314                                if (now >= (s.lastActivity
15315                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15316                                    // This service has not seen activity within
15317                                    // recent memory, so allow it to drop to the
15318                                    // LRU list if there is no other reason to keep
15319                                    // it around.  We'll also tag it with a label just
15320                                    // to help debug and undertand what is going on.
15321                                    if (adj > clientAdj) {
15322                                        adjType = "cch-bound-services";
15323                                    }
15324                                    clientAdj = adj;
15325                                }
15326                            }
15327                        }
15328                        if (adj > clientAdj) {
15329                            // If this process has recently shown UI, and
15330                            // the process that is binding to it is less
15331                            // important than being visible, then we don't
15332                            // care about the binding as much as we care
15333                            // about letting this process get into the LRU
15334                            // list to be killed and restarted if needed for
15335                            // memory.
15336                            if (app.hasShownUi && app != mHomeProcess
15337                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15338                                adjType = "cch-bound-ui-services";
15339                            } else {
15340                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15341                                        |Context.BIND_IMPORTANT)) != 0) {
15342                                    adj = clientAdj;
15343                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15344                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15345                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15346                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15347                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15348                                    adj = clientAdj;
15349                                } else {
15350                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15351                                        adj = ProcessList.VISIBLE_APP_ADJ;
15352                                    }
15353                                }
15354                                if (!client.cached) {
15355                                    app.cached = false;
15356                                }
15357                                if (client.keeping) {
15358                                    app.keeping = true;
15359                                }
15360                                adjType = "service";
15361                            }
15362                        }
15363                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15364                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15365                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15366                            }
15367                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15368                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15369                                    // Special handling of clients who are in the top state.
15370                                    // We *may* want to consider this process to be in the
15371                                    // top state as well, but only if there is not another
15372                                    // reason for it to be running.  Being on the top is a
15373                                    // special state, meaning you are specifically running
15374                                    // for the current top app.  If the process is already
15375                                    // running in the background for some other reason, it
15376                                    // is more important to continue considering it to be
15377                                    // in the background state.
15378                                    mayBeTop = true;
15379                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15380                                } else {
15381                                    // Special handling for above-top states (persistent
15382                                    // processes).  These should not bring the current process
15383                                    // into the top state, since they are not on top.  Instead
15384                                    // give them the best state after that.
15385                                    clientProcState =
15386                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15387                                }
15388                            }
15389                        } else {
15390                            if (clientProcState <
15391                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15392                                clientProcState =
15393                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15394                            }
15395                        }
15396                        if (procState > clientProcState) {
15397                            procState = clientProcState;
15398                        }
15399                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15400                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15401                            app.pendingUiClean = true;
15402                        }
15403                        if (adjType != null) {
15404                            app.adjType = adjType;
15405                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15406                                    .REASON_SERVICE_IN_USE;
15407                            app.adjSource = cr.binding.client;
15408                            app.adjSourceOom = clientAdj;
15409                            app.adjTarget = s.name;
15410                        }
15411                    }
15412                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15413                        app.treatLikeActivity = true;
15414                    }
15415                    final ActivityRecord a = cr.activity;
15416                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15417                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15418                                (a.visible || a.state == ActivityState.RESUMED
15419                                 || a.state == ActivityState.PAUSING)) {
15420                            adj = ProcessList.FOREGROUND_APP_ADJ;
15421                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15422                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15423                            }
15424                            app.cached = false;
15425                            app.adjType = "service";
15426                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15427                                    .REASON_SERVICE_IN_USE;
15428                            app.adjSource = a;
15429                            app.adjSourceOom = adj;
15430                            app.adjTarget = s.name;
15431                        }
15432                    }
15433                }
15434            }
15435        }
15436
15437        for (int provi = app.pubProviders.size()-1;
15438                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15439                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15440                        || procState > ActivityManager.PROCESS_STATE_TOP);
15441                provi--) {
15442            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15443            for (int i = cpr.connections.size()-1;
15444                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15445                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15446                            || procState > ActivityManager.PROCESS_STATE_TOP);
15447                    i--) {
15448                ContentProviderConnection conn = cpr.connections.get(i);
15449                ProcessRecord client = conn.client;
15450                if (client == app) {
15451                    // Being our own client is not interesting.
15452                    continue;
15453                }
15454                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15455                int clientProcState = client.curProcState;
15456                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15457                    // If the other app is cached for any reason, for purposes here
15458                    // we are going to consider it empty.
15459                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15460                }
15461                if (adj > clientAdj) {
15462                    if (app.hasShownUi && app != mHomeProcess
15463                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15464                        app.adjType = "cch-ui-provider";
15465                    } else {
15466                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15467                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15468                        app.adjType = "provider";
15469                    }
15470                    app.cached &= client.cached;
15471                    app.keeping |= client.keeping;
15472                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15473                            .REASON_PROVIDER_IN_USE;
15474                    app.adjSource = client;
15475                    app.adjSourceOom = clientAdj;
15476                    app.adjTarget = cpr.name;
15477                }
15478                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15479                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15480                        // Special handling of clients who are in the top state.
15481                        // We *may* want to consider this process to be in the
15482                        // top state as well, but only if there is not another
15483                        // reason for it to be running.  Being on the top is a
15484                        // special state, meaning you are specifically running
15485                        // for the current top app.  If the process is already
15486                        // running in the background for some other reason, it
15487                        // is more important to continue considering it to be
15488                        // in the background state.
15489                        mayBeTop = true;
15490                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15491                    } else {
15492                        // Special handling for above-top states (persistent
15493                        // processes).  These should not bring the current process
15494                        // into the top state, since they are not on top.  Instead
15495                        // give them the best state after that.
15496                        clientProcState =
15497                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15498                    }
15499                }
15500                if (procState > clientProcState) {
15501                    procState = clientProcState;
15502                }
15503                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15504                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15505                }
15506            }
15507            // If the provider has external (non-framework) process
15508            // dependencies, ensure that its adjustment is at least
15509            // FOREGROUND_APP_ADJ.
15510            if (cpr.hasExternalProcessHandles()) {
15511                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15512                    adj = ProcessList.FOREGROUND_APP_ADJ;
15513                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15514                    app.cached = false;
15515                    app.keeping = true;
15516                    app.adjType = "provider";
15517                    app.adjTarget = cpr.name;
15518                }
15519                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15520                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15521                }
15522            }
15523        }
15524
15525        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15526            // A client of one of our services or providers is in the top state.  We
15527            // *may* want to be in the top state, but not if we are already running in
15528            // the background for some other reason.  For the decision here, we are going
15529            // to pick out a few specific states that we want to remain in when a client
15530            // is top (states that tend to be longer-term) and otherwise allow it to go
15531            // to the top state.
15532            switch (procState) {
15533                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15534                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15535                case ActivityManager.PROCESS_STATE_SERVICE:
15536                    // These all are longer-term states, so pull them up to the top
15537                    // of the background states, but not all the way to the top state.
15538                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15539                    break;
15540                default:
15541                    // Otherwise, top is a better choice, so take it.
15542                    procState = ActivityManager.PROCESS_STATE_TOP;
15543                    break;
15544            }
15545        }
15546
15547        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15548            if (app.hasClientActivities) {
15549                // This is a cached process, but with client activities.  Mark it so.
15550                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15551                app.adjType = "cch-client-act";
15552            } else if (app.treatLikeActivity) {
15553                // This is a cached process, but somebody wants us to treat it like it has
15554                // an activity, okay!
15555                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15556                app.adjType = "cch-as-act";
15557            }
15558        }
15559
15560        if (adj == ProcessList.SERVICE_ADJ) {
15561            if (doingAll) {
15562                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15563                mNewNumServiceProcs++;
15564                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15565                if (!app.serviceb) {
15566                    // This service isn't far enough down on the LRU list to
15567                    // normally be a B service, but if we are low on RAM and it
15568                    // is large we want to force it down since we would prefer to
15569                    // keep launcher over it.
15570                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15571                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15572                        app.serviceHighRam = true;
15573                        app.serviceb = true;
15574                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15575                    } else {
15576                        mNewNumAServiceProcs++;
15577                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15578                    }
15579                } else {
15580                    app.serviceHighRam = false;
15581                }
15582            }
15583            if (app.serviceb) {
15584                adj = ProcessList.SERVICE_B_ADJ;
15585            }
15586        }
15587
15588        app.curRawAdj = adj;
15589
15590        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15591        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15592        if (adj > app.maxAdj) {
15593            adj = app.maxAdj;
15594            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15595                schedGroup = Process.THREAD_GROUP_DEFAULT;
15596            }
15597        }
15598        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15599            app.keeping = true;
15600        }
15601
15602        // Do final modification to adj.  Everything we do between here and applying
15603        // the final setAdj must be done in this function, because we will also use
15604        // it when computing the final cached adj later.  Note that we don't need to
15605        // worry about this for max adj above, since max adj will always be used to
15606        // keep it out of the cached vaues.
15607        app.curAdj = app.modifyRawOomAdj(adj);
15608        app.curSchedGroup = schedGroup;
15609        app.curProcState = procState;
15610        app.foregroundActivities = foregroundActivities;
15611
15612        return app.curRawAdj;
15613    }
15614
15615    /**
15616     * Schedule PSS collection of a process.
15617     */
15618    void requestPssLocked(ProcessRecord proc, int procState) {
15619        if (mPendingPssProcesses.contains(proc)) {
15620            return;
15621        }
15622        if (mPendingPssProcesses.size() == 0) {
15623            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15624        }
15625        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15626        proc.pssProcState = procState;
15627        mPendingPssProcesses.add(proc);
15628    }
15629
15630    /**
15631     * Schedule PSS collection of all processes.
15632     */
15633    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15634        if (!always) {
15635            if (now < (mLastFullPssTime +
15636                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15637                return;
15638            }
15639        }
15640        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15641        mLastFullPssTime = now;
15642        mFullPssPending = true;
15643        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15644        mPendingPssProcesses.clear();
15645        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15646            ProcessRecord app = mLruProcesses.get(i);
15647            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15648                app.pssProcState = app.setProcState;
15649                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15650                        isSleeping(), now);
15651                mPendingPssProcesses.add(app);
15652            }
15653        }
15654        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15655    }
15656
15657    /**
15658     * Ask a given process to GC right now.
15659     */
15660    final void performAppGcLocked(ProcessRecord app) {
15661        try {
15662            app.lastRequestedGc = SystemClock.uptimeMillis();
15663            if (app.thread != null) {
15664                if (app.reportLowMemory) {
15665                    app.reportLowMemory = false;
15666                    app.thread.scheduleLowMemory();
15667                } else {
15668                    app.thread.processInBackground();
15669                }
15670            }
15671        } catch (Exception e) {
15672            // whatever.
15673        }
15674    }
15675
15676    /**
15677     * Returns true if things are idle enough to perform GCs.
15678     */
15679    private final boolean canGcNowLocked() {
15680        boolean processingBroadcasts = false;
15681        for (BroadcastQueue q : mBroadcastQueues) {
15682            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15683                processingBroadcasts = true;
15684            }
15685        }
15686        return !processingBroadcasts
15687                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15688    }
15689
15690    /**
15691     * Perform GCs on all processes that are waiting for it, but only
15692     * if things are idle.
15693     */
15694    final void performAppGcsLocked() {
15695        final int N = mProcessesToGc.size();
15696        if (N <= 0) {
15697            return;
15698        }
15699        if (canGcNowLocked()) {
15700            while (mProcessesToGc.size() > 0) {
15701                ProcessRecord proc = mProcessesToGc.remove(0);
15702                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15703                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15704                            <= SystemClock.uptimeMillis()) {
15705                        // To avoid spamming the system, we will GC processes one
15706                        // at a time, waiting a few seconds between each.
15707                        performAppGcLocked(proc);
15708                        scheduleAppGcsLocked();
15709                        return;
15710                    } else {
15711                        // It hasn't been long enough since we last GCed this
15712                        // process...  put it in the list to wait for its time.
15713                        addProcessToGcListLocked(proc);
15714                        break;
15715                    }
15716                }
15717            }
15718
15719            scheduleAppGcsLocked();
15720        }
15721    }
15722
15723    /**
15724     * If all looks good, perform GCs on all processes waiting for them.
15725     */
15726    final void performAppGcsIfAppropriateLocked() {
15727        if (canGcNowLocked()) {
15728            performAppGcsLocked();
15729            return;
15730        }
15731        // Still not idle, wait some more.
15732        scheduleAppGcsLocked();
15733    }
15734
15735    /**
15736     * Schedule the execution of all pending app GCs.
15737     */
15738    final void scheduleAppGcsLocked() {
15739        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15740
15741        if (mProcessesToGc.size() > 0) {
15742            // Schedule a GC for the time to the next process.
15743            ProcessRecord proc = mProcessesToGc.get(0);
15744            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15745
15746            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15747            long now = SystemClock.uptimeMillis();
15748            if (when < (now+GC_TIMEOUT)) {
15749                when = now + GC_TIMEOUT;
15750            }
15751            mHandler.sendMessageAtTime(msg, when);
15752        }
15753    }
15754
15755    /**
15756     * Add a process to the array of processes waiting to be GCed.  Keeps the
15757     * list in sorted order by the last GC time.  The process can't already be
15758     * on the list.
15759     */
15760    final void addProcessToGcListLocked(ProcessRecord proc) {
15761        boolean added = false;
15762        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15763            if (mProcessesToGc.get(i).lastRequestedGc <
15764                    proc.lastRequestedGc) {
15765                added = true;
15766                mProcessesToGc.add(i+1, proc);
15767                break;
15768            }
15769        }
15770        if (!added) {
15771            mProcessesToGc.add(0, proc);
15772        }
15773    }
15774
15775    /**
15776     * Set up to ask a process to GC itself.  This will either do it
15777     * immediately, or put it on the list of processes to gc the next
15778     * time things are idle.
15779     */
15780    final void scheduleAppGcLocked(ProcessRecord app) {
15781        long now = SystemClock.uptimeMillis();
15782        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15783            return;
15784        }
15785        if (!mProcessesToGc.contains(app)) {
15786            addProcessToGcListLocked(app);
15787            scheduleAppGcsLocked();
15788        }
15789    }
15790
15791    final void checkExcessivePowerUsageLocked(boolean doKills) {
15792        updateCpuStatsNow();
15793
15794        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15795        boolean doWakeKills = doKills;
15796        boolean doCpuKills = doKills;
15797        if (mLastPowerCheckRealtime == 0) {
15798            doWakeKills = false;
15799        }
15800        if (mLastPowerCheckUptime == 0) {
15801            doCpuKills = false;
15802        }
15803        if (stats.isScreenOn()) {
15804            doWakeKills = false;
15805        }
15806        final long curRealtime = SystemClock.elapsedRealtime();
15807        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15808        final long curUptime = SystemClock.uptimeMillis();
15809        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15810        mLastPowerCheckRealtime = curRealtime;
15811        mLastPowerCheckUptime = curUptime;
15812        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15813            doWakeKills = false;
15814        }
15815        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15816            doCpuKills = false;
15817        }
15818        int i = mLruProcesses.size();
15819        while (i > 0) {
15820            i--;
15821            ProcessRecord app = mLruProcesses.get(i);
15822            if (!app.keeping) {
15823                long wtime;
15824                synchronized (stats) {
15825                    wtime = stats.getProcessWakeTime(app.info.uid,
15826                            app.pid, curRealtime);
15827                }
15828                long wtimeUsed = wtime - app.lastWakeTime;
15829                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15830                if (DEBUG_POWER) {
15831                    StringBuilder sb = new StringBuilder(128);
15832                    sb.append("Wake for ");
15833                    app.toShortString(sb);
15834                    sb.append(": over ");
15835                    TimeUtils.formatDuration(realtimeSince, sb);
15836                    sb.append(" used ");
15837                    TimeUtils.formatDuration(wtimeUsed, sb);
15838                    sb.append(" (");
15839                    sb.append((wtimeUsed*100)/realtimeSince);
15840                    sb.append("%)");
15841                    Slog.i(TAG, sb.toString());
15842                    sb.setLength(0);
15843                    sb.append("CPU for ");
15844                    app.toShortString(sb);
15845                    sb.append(": over ");
15846                    TimeUtils.formatDuration(uptimeSince, sb);
15847                    sb.append(" used ");
15848                    TimeUtils.formatDuration(cputimeUsed, sb);
15849                    sb.append(" (");
15850                    sb.append((cputimeUsed*100)/uptimeSince);
15851                    sb.append("%)");
15852                    Slog.i(TAG, sb.toString());
15853                }
15854                // If a process has held a wake lock for more
15855                // than 50% of the time during this period,
15856                // that sounds bad.  Kill!
15857                if (doWakeKills && realtimeSince > 0
15858                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15859                    synchronized (stats) {
15860                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15861                                realtimeSince, wtimeUsed);
15862                    }
15863                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15864                            + " during " + realtimeSince);
15865                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15866                } else if (doCpuKills && uptimeSince > 0
15867                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15868                    synchronized (stats) {
15869                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15870                                uptimeSince, cputimeUsed);
15871                    }
15872                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15873                            + " during " + uptimeSince);
15874                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15875                } else {
15876                    app.lastWakeTime = wtime;
15877                    app.lastCpuTime = app.curCpuTime;
15878                }
15879            }
15880        }
15881    }
15882
15883    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15884            ProcessRecord TOP_APP, boolean doingAll, long now) {
15885        boolean success = true;
15886
15887        if (app.curRawAdj != app.setRawAdj) {
15888            if (wasKeeping && !app.keeping) {
15889                // This app is no longer something we want to keep.  Note
15890                // its current wake lock time to later know to kill it if
15891                // it is not behaving well.
15892                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15893                synchronized (stats) {
15894                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15895                            app.pid, SystemClock.elapsedRealtime());
15896                }
15897                app.lastCpuTime = app.curCpuTime;
15898            }
15899
15900            app.setRawAdj = app.curRawAdj;
15901        }
15902
15903        int changes = 0;
15904
15905        if (app.curAdj != app.setAdj) {
15906            ProcessList.setOomAdj(app.pid, app.curAdj);
15907            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15908                TAG, "Set " + app.pid + " " + app.processName +
15909                " adj " + app.curAdj + ": " + app.adjType);
15910            app.setAdj = app.curAdj;
15911        }
15912
15913        if (app.setSchedGroup != app.curSchedGroup) {
15914            app.setSchedGroup = app.curSchedGroup;
15915            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15916                    "Setting process group of " + app.processName
15917                    + " to " + app.curSchedGroup);
15918            if (app.waitingToKill != null &&
15919                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15920                killUnneededProcessLocked(app, app.waitingToKill);
15921                success = false;
15922            } else {
15923                if (true) {
15924                    long oldId = Binder.clearCallingIdentity();
15925                    try {
15926                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15927                    } catch (Exception e) {
15928                        Slog.w(TAG, "Failed setting process group of " + app.pid
15929                                + " to " + app.curSchedGroup);
15930                        e.printStackTrace();
15931                    } finally {
15932                        Binder.restoreCallingIdentity(oldId);
15933                    }
15934                } else {
15935                    if (app.thread != null) {
15936                        try {
15937                            app.thread.setSchedulingGroup(app.curSchedGroup);
15938                        } catch (RemoteException e) {
15939                        }
15940                    }
15941                }
15942                Process.setSwappiness(app.pid,
15943                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15944            }
15945        }
15946        if (app.repForegroundActivities != app.foregroundActivities) {
15947            app.repForegroundActivities = app.foregroundActivities;
15948            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15949        }
15950        if (app.repProcState != app.curProcState) {
15951            app.repProcState = app.curProcState;
15952            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
15953            if (app.thread != null) {
15954                try {
15955                    if (false) {
15956                        //RuntimeException h = new RuntimeException("here");
15957                        Slog.i(TAG, "Sending new process state " + app.repProcState
15958                                + " to " + app /*, h*/);
15959                    }
15960                    app.thread.setProcessState(app.repProcState);
15961                } catch (RemoteException e) {
15962                }
15963            }
15964        }
15965        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15966                app.setProcState)) {
15967            app.lastStateTime = now;
15968            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15969                    isSleeping(), now);
15970            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15971                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15972                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15973                    + (app.nextPssTime-now) + ": " + app);
15974        } else {
15975            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15976                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15977                requestPssLocked(app, app.setProcState);
15978                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15979                        isSleeping(), now);
15980            } else if (false && DEBUG_PSS) {
15981                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15982            }
15983        }
15984        if (app.setProcState != app.curProcState) {
15985            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15986                    "Proc state change of " + app.processName
15987                    + " to " + app.curProcState);
15988            app.setProcState = app.curProcState;
15989            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15990                app.notCachedSinceIdle = false;
15991            }
15992            if (!doingAll) {
15993                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15994            } else {
15995                app.procStateChanged = true;
15996            }
15997        }
15998
15999        if (changes != 0) {
16000            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
16001            int i = mPendingProcessChanges.size()-1;
16002            ProcessChangeItem item = null;
16003            while (i >= 0) {
16004                item = mPendingProcessChanges.get(i);
16005                if (item.pid == app.pid) {
16006                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
16007                    break;
16008                }
16009                i--;
16010            }
16011            if (i < 0) {
16012                // No existing item in pending changes; need a new one.
16013                final int NA = mAvailProcessChanges.size();
16014                if (NA > 0) {
16015                    item = mAvailProcessChanges.remove(NA-1);
16016                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
16017                } else {
16018                    item = new ProcessChangeItem();
16019                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
16020                }
16021                item.changes = 0;
16022                item.pid = app.pid;
16023                item.uid = app.info.uid;
16024                if (mPendingProcessChanges.size() == 0) {
16025                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
16026                            "*** Enqueueing dispatch processes changed!");
16027                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
16028                }
16029                mPendingProcessChanges.add(item);
16030            }
16031            item.changes |= changes;
16032            item.processState = app.repProcState;
16033            item.foregroundActivities = app.repForegroundActivities;
16034            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16035                    + Integer.toHexString(System.identityHashCode(item))
16036                    + " " + app.toShortString() + ": changes=" + item.changes
16037                    + " procState=" + item.processState
16038                    + " foreground=" + item.foregroundActivities
16039                    + " type=" + app.adjType + " source=" + app.adjSource
16040                    + " target=" + app.adjTarget);
16041        }
16042
16043        return success;
16044    }
16045
16046    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
16047        if (proc.thread != null && proc.baseProcessTracker != null) {
16048            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16049        }
16050    }
16051
16052    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16053            ProcessRecord TOP_APP, boolean doingAll, long now) {
16054        if (app.thread == null) {
16055            return false;
16056        }
16057
16058        final boolean wasKeeping = app.keeping;
16059
16060        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16061
16062        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now);
16063    }
16064
16065    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16066            boolean oomAdj) {
16067        if (isForeground != proc.foregroundServices) {
16068            proc.foregroundServices = isForeground;
16069            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16070                    proc.info.uid);
16071            if (isForeground) {
16072                if (curProcs == null) {
16073                    curProcs = new ArrayList<ProcessRecord>();
16074                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16075                }
16076                if (!curProcs.contains(proc)) {
16077                    curProcs.add(proc);
16078                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16079                            proc.info.packageName, proc.info.uid);
16080                }
16081            } else {
16082                if (curProcs != null) {
16083                    if (curProcs.remove(proc)) {
16084                        mBatteryStatsService.noteEvent(
16085                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16086                                proc.info.packageName, proc.info.uid);
16087                        if (curProcs.size() <= 0) {
16088                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16089                        }
16090                    }
16091                }
16092            }
16093            if (oomAdj) {
16094                updateOomAdjLocked();
16095            }
16096        }
16097    }
16098
16099    private final ActivityRecord resumedAppLocked() {
16100        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16101        String pkg;
16102        int uid;
16103        if (act != null && !act.sleeping) {
16104            pkg = act.packageName;
16105            uid = act.info.applicationInfo.uid;
16106        } else {
16107            pkg = null;
16108            uid = -1;
16109        }
16110        // Has the UID or resumed package name changed?
16111        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16112                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16113            if (mCurResumedPackage != null) {
16114                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16115                        mCurResumedPackage, mCurResumedUid);
16116            }
16117            mCurResumedPackage = pkg;
16118            mCurResumedUid = uid;
16119            if (mCurResumedPackage != null) {
16120                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16121                        mCurResumedPackage, mCurResumedUid);
16122            }
16123        }
16124        return act;
16125    }
16126
16127    final boolean updateOomAdjLocked(ProcessRecord app) {
16128        final ActivityRecord TOP_ACT = resumedAppLocked();
16129        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16130        final boolean wasCached = app.cached;
16131
16132        mAdjSeq++;
16133
16134        // This is the desired cached adjusment we want to tell it to use.
16135        // If our app is currently cached, we know it, and that is it.  Otherwise,
16136        // we don't know it yet, and it needs to now be cached we will then
16137        // need to do a complete oom adj.
16138        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16139                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16140        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16141                SystemClock.uptimeMillis());
16142        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16143            // Changed to/from cached state, so apps after it in the LRU
16144            // list may also be changed.
16145            updateOomAdjLocked();
16146        }
16147        return success;
16148    }
16149
16150    final void updateOomAdjLocked() {
16151        final ActivityRecord TOP_ACT = resumedAppLocked();
16152        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16153        final long now = SystemClock.uptimeMillis();
16154        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16155        final int N = mLruProcesses.size();
16156
16157        if (false) {
16158            RuntimeException e = new RuntimeException();
16159            e.fillInStackTrace();
16160            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16161        }
16162
16163        mAdjSeq++;
16164        mNewNumServiceProcs = 0;
16165        mNewNumAServiceProcs = 0;
16166
16167        final int emptyProcessLimit;
16168        final int cachedProcessLimit;
16169        if (mProcessLimit <= 0) {
16170            emptyProcessLimit = cachedProcessLimit = 0;
16171        } else if (mProcessLimit == 1) {
16172            emptyProcessLimit = 1;
16173            cachedProcessLimit = 0;
16174        } else {
16175            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16176            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16177        }
16178
16179        // Let's determine how many processes we have running vs.
16180        // how many slots we have for background processes; we may want
16181        // to put multiple processes in a slot of there are enough of
16182        // them.
16183        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16184                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16185        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16186        if (numEmptyProcs > cachedProcessLimit) {
16187            // If there are more empty processes than our limit on cached
16188            // processes, then use the cached process limit for the factor.
16189            // This ensures that the really old empty processes get pushed
16190            // down to the bottom, so if we are running low on memory we will
16191            // have a better chance at keeping around more cached processes
16192            // instead of a gazillion empty processes.
16193            numEmptyProcs = cachedProcessLimit;
16194        }
16195        int emptyFactor = numEmptyProcs/numSlots;
16196        if (emptyFactor < 1) emptyFactor = 1;
16197        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16198        if (cachedFactor < 1) cachedFactor = 1;
16199        int stepCached = 0;
16200        int stepEmpty = 0;
16201        int numCached = 0;
16202        int numEmpty = 0;
16203        int numTrimming = 0;
16204
16205        mNumNonCachedProcs = 0;
16206        mNumCachedHiddenProcs = 0;
16207
16208        // First update the OOM adjustment for each of the
16209        // application processes based on their current state.
16210        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16211        int nextCachedAdj = curCachedAdj+1;
16212        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16213        int nextEmptyAdj = curEmptyAdj+2;
16214        for (int i=N-1; i>=0; i--) {
16215            ProcessRecord app = mLruProcesses.get(i);
16216            if (!app.killedByAm && app.thread != null) {
16217                app.procStateChanged = false;
16218                final boolean wasKeeping = app.keeping;
16219                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16220
16221                // If we haven't yet assigned the final cached adj
16222                // to the process, do that now.
16223                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16224                    switch (app.curProcState) {
16225                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16226                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16227                            // This process is a cached process holding activities...
16228                            // assign it the next cached value for that type, and then
16229                            // step that cached level.
16230                            app.curRawAdj = curCachedAdj;
16231                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16232                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16233                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16234                                    + ")");
16235                            if (curCachedAdj != nextCachedAdj) {
16236                                stepCached++;
16237                                if (stepCached >= cachedFactor) {
16238                                    stepCached = 0;
16239                                    curCachedAdj = nextCachedAdj;
16240                                    nextCachedAdj += 2;
16241                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16242                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16243                                    }
16244                                }
16245                            }
16246                            break;
16247                        default:
16248                            // For everything else, assign next empty cached process
16249                            // level and bump that up.  Note that this means that
16250                            // long-running services that have dropped down to the
16251                            // cached level will be treated as empty (since their process
16252                            // state is still as a service), which is what we want.
16253                            app.curRawAdj = curEmptyAdj;
16254                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16255                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16256                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16257                                    + ")");
16258                            if (curEmptyAdj != nextEmptyAdj) {
16259                                stepEmpty++;
16260                                if (stepEmpty >= emptyFactor) {
16261                                    stepEmpty = 0;
16262                                    curEmptyAdj = nextEmptyAdj;
16263                                    nextEmptyAdj += 2;
16264                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16265                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16266                                    }
16267                                }
16268                            }
16269                            break;
16270                    }
16271                }
16272
16273                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now);
16274
16275                // Count the number of process types.
16276                switch (app.curProcState) {
16277                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16278                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16279                        mNumCachedHiddenProcs++;
16280                        numCached++;
16281                        if (numCached > cachedProcessLimit) {
16282                            killUnneededProcessLocked(app, "cached #" + numCached);
16283                        }
16284                        break;
16285                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16286                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16287                                && app.lastActivityTime < oldTime) {
16288                            killUnneededProcessLocked(app, "empty for "
16289                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16290                                    / 1000) + "s");
16291                        } else {
16292                            numEmpty++;
16293                            if (numEmpty > emptyProcessLimit) {
16294                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16295                            }
16296                        }
16297                        break;
16298                    default:
16299                        mNumNonCachedProcs++;
16300                        break;
16301                }
16302
16303                if (app.isolated && app.services.size() <= 0) {
16304                    // If this is an isolated process, and there are no
16305                    // services running in it, then the process is no longer
16306                    // needed.  We agressively kill these because we can by
16307                    // definition not re-use the same process again, and it is
16308                    // good to avoid having whatever code was running in them
16309                    // left sitting around after no longer needed.
16310                    killUnneededProcessLocked(app, "isolated not needed");
16311                }
16312
16313                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16314                        && !app.killedByAm) {
16315                    numTrimming++;
16316                }
16317            }
16318        }
16319
16320        mNumServiceProcs = mNewNumServiceProcs;
16321
16322        // Now determine the memory trimming level of background processes.
16323        // Unfortunately we need to start at the back of the list to do this
16324        // properly.  We only do this if the number of background apps we
16325        // are managing to keep around is less than half the maximum we desire;
16326        // if we are keeping a good number around, we'll let them use whatever
16327        // memory they want.
16328        final int numCachedAndEmpty = numCached + numEmpty;
16329        int memFactor;
16330        if (numCached <= ProcessList.TRIM_CACHED_APPS
16331                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16332            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16333                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16334            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16335                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16336            } else {
16337                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16338            }
16339        } else {
16340            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16341        }
16342        // We always allow the memory level to go up (better).  We only allow it to go
16343        // down if we are in a state where that is allowed, *and* the total number of processes
16344        // has gone down since last time.
16345        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16346                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16347                + " last=" + mLastNumProcesses);
16348        if (memFactor > mLastMemoryLevel) {
16349            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16350                memFactor = mLastMemoryLevel;
16351                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16352            }
16353        }
16354        mLastMemoryLevel = memFactor;
16355        mLastNumProcesses = mLruProcesses.size();
16356        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16357        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16358        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16359            if (mLowRamStartTime == 0) {
16360                mLowRamStartTime = now;
16361            }
16362            int step = 0;
16363            int fgTrimLevel;
16364            switch (memFactor) {
16365                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16366                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16367                    break;
16368                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16369                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16370                    break;
16371                default:
16372                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16373                    break;
16374            }
16375            int factor = numTrimming/3;
16376            int minFactor = 2;
16377            if (mHomeProcess != null) minFactor++;
16378            if (mPreviousProcess != null) minFactor++;
16379            if (factor < minFactor) factor = minFactor;
16380            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16381            for (int i=N-1; i>=0; i--) {
16382                ProcessRecord app = mLruProcesses.get(i);
16383                if (allChanged || app.procStateChanged) {
16384                    setProcessTrackerState(app, trackerMemFactor, now);
16385                    app.procStateChanged = false;
16386                }
16387                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16388                        && !app.killedByAm) {
16389                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16390                        try {
16391                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16392                                    "Trimming memory of " + app.processName
16393                                    + " to " + curLevel);
16394                            app.thread.scheduleTrimMemory(curLevel);
16395                        } catch (RemoteException e) {
16396                        }
16397                        if (false) {
16398                            // For now we won't do this; our memory trimming seems
16399                            // to be good enough at this point that destroying
16400                            // activities causes more harm than good.
16401                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16402                                    && app != mHomeProcess && app != mPreviousProcess) {
16403                                // Need to do this on its own message because the stack may not
16404                                // be in a consistent state at this point.
16405                                // For these apps we will also finish their activities
16406                                // to help them free memory.
16407                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16408                            }
16409                        }
16410                    }
16411                    app.trimMemoryLevel = curLevel;
16412                    step++;
16413                    if (step >= factor) {
16414                        step = 0;
16415                        switch (curLevel) {
16416                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16417                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16418                                break;
16419                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16420                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16421                                break;
16422                        }
16423                    }
16424                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16425                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16426                            && app.thread != null) {
16427                        try {
16428                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16429                                    "Trimming memory of heavy-weight " + app.processName
16430                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16431                            app.thread.scheduleTrimMemory(
16432                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16433                        } catch (RemoteException e) {
16434                        }
16435                    }
16436                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16437                } else {
16438                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16439                            || app.systemNoUi) && app.pendingUiClean) {
16440                        // If this application is now in the background and it
16441                        // had done UI, then give it the special trim level to
16442                        // have it free UI resources.
16443                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16444                        if (app.trimMemoryLevel < level && app.thread != null) {
16445                            try {
16446                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16447                                        "Trimming memory of bg-ui " + app.processName
16448                                        + " to " + level);
16449                                app.thread.scheduleTrimMemory(level);
16450                            } catch (RemoteException e) {
16451                            }
16452                        }
16453                        app.pendingUiClean = false;
16454                    }
16455                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16456                        try {
16457                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16458                                    "Trimming memory of fg " + app.processName
16459                                    + " to " + fgTrimLevel);
16460                            app.thread.scheduleTrimMemory(fgTrimLevel);
16461                        } catch (RemoteException e) {
16462                        }
16463                    }
16464                    app.trimMemoryLevel = fgTrimLevel;
16465                }
16466            }
16467        } else {
16468            if (mLowRamStartTime != 0) {
16469                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16470                mLowRamStartTime = 0;
16471            }
16472            for (int i=N-1; i>=0; i--) {
16473                ProcessRecord app = mLruProcesses.get(i);
16474                if (allChanged || app.procStateChanged) {
16475                    setProcessTrackerState(app, trackerMemFactor, now);
16476                    app.procStateChanged = false;
16477                }
16478                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16479                        || app.systemNoUi) && app.pendingUiClean) {
16480                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16481                            && app.thread != null) {
16482                        try {
16483                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16484                                    "Trimming memory of ui hidden " + app.processName
16485                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16486                            app.thread.scheduleTrimMemory(
16487                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16488                        } catch (RemoteException e) {
16489                        }
16490                    }
16491                    app.pendingUiClean = false;
16492                }
16493                app.trimMemoryLevel = 0;
16494            }
16495        }
16496
16497        if (mAlwaysFinishActivities) {
16498            // Need to do this on its own message because the stack may not
16499            // be in a consistent state at this point.
16500            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16501        }
16502
16503        if (allChanged) {
16504            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16505        }
16506
16507        if (mProcessStats.shouldWriteNowLocked(now)) {
16508            mHandler.post(new Runnable() {
16509                @Override public void run() {
16510                    synchronized (ActivityManagerService.this) {
16511                        mProcessStats.writeStateAsyncLocked();
16512                    }
16513                }
16514            });
16515        }
16516
16517        if (DEBUG_OOM_ADJ) {
16518            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16519        }
16520    }
16521
16522    final void trimApplications() {
16523        synchronized (this) {
16524            int i;
16525
16526            // First remove any unused application processes whose package
16527            // has been removed.
16528            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16529                final ProcessRecord app = mRemovedProcesses.get(i);
16530                if (app.activities.size() == 0
16531                        && app.curReceiver == null && app.services.size() == 0) {
16532                    Slog.i(
16533                        TAG, "Exiting empty application process "
16534                        + app.processName + " ("
16535                        + (app.thread != null ? app.thread.asBinder() : null)
16536                        + ")\n");
16537                    if (app.pid > 0 && app.pid != MY_PID) {
16538                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16539                                app.processName, app.setAdj, "empty");
16540                        app.killedByAm = true;
16541                        Process.killProcessQuiet(app.pid);
16542                    } else {
16543                        try {
16544                            app.thread.scheduleExit();
16545                        } catch (Exception e) {
16546                            // Ignore exceptions.
16547                        }
16548                    }
16549                    cleanUpApplicationRecordLocked(app, false, true, -1);
16550                    mRemovedProcesses.remove(i);
16551
16552                    if (app.persistent) {
16553                        if (app.persistent) {
16554                            addAppLocked(app.info, false, null /* ABI override */);
16555                        }
16556                    }
16557                }
16558            }
16559
16560            // Now update the oom adj for all processes.
16561            updateOomAdjLocked();
16562        }
16563    }
16564
16565    /** This method sends the specified signal to each of the persistent apps */
16566    public void signalPersistentProcesses(int sig) throws RemoteException {
16567        if (sig != Process.SIGNAL_USR1) {
16568            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16569        }
16570
16571        synchronized (this) {
16572            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16573                    != PackageManager.PERMISSION_GRANTED) {
16574                throw new SecurityException("Requires permission "
16575                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16576            }
16577
16578            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16579                ProcessRecord r = mLruProcesses.get(i);
16580                if (r.thread != null && r.persistent) {
16581                    Process.sendSignal(r.pid, sig);
16582                }
16583            }
16584        }
16585    }
16586
16587    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16588        if (proc == null || proc == mProfileProc) {
16589            proc = mProfileProc;
16590            path = mProfileFile;
16591            profileType = mProfileType;
16592            clearProfilerLocked();
16593        }
16594        if (proc == null) {
16595            return;
16596        }
16597        try {
16598            proc.thread.profilerControl(false, path, null, profileType);
16599        } catch (RemoteException e) {
16600            throw new IllegalStateException("Process disappeared");
16601        }
16602    }
16603
16604    private void clearProfilerLocked() {
16605        if (mProfileFd != null) {
16606            try {
16607                mProfileFd.close();
16608            } catch (IOException e) {
16609            }
16610        }
16611        mProfileApp = null;
16612        mProfileProc = null;
16613        mProfileFile = null;
16614        mProfileType = 0;
16615        mAutoStopProfiler = false;
16616    }
16617
16618    public boolean profileControl(String process, int userId, boolean start,
16619            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16620
16621        try {
16622            synchronized (this) {
16623                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16624                // its own permission.
16625                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16626                        != PackageManager.PERMISSION_GRANTED) {
16627                    throw new SecurityException("Requires permission "
16628                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16629                }
16630
16631                if (start && fd == null) {
16632                    throw new IllegalArgumentException("null fd");
16633                }
16634
16635                ProcessRecord proc = null;
16636                if (process != null) {
16637                    proc = findProcessLocked(process, userId, "profileControl");
16638                }
16639
16640                if (start && (proc == null || proc.thread == null)) {
16641                    throw new IllegalArgumentException("Unknown process: " + process);
16642                }
16643
16644                if (start) {
16645                    stopProfilerLocked(null, null, 0);
16646                    setProfileApp(proc.info, proc.processName, path, fd, false);
16647                    mProfileProc = proc;
16648                    mProfileType = profileType;
16649                    try {
16650                        fd = fd.dup();
16651                    } catch (IOException e) {
16652                        fd = null;
16653                    }
16654                    proc.thread.profilerControl(start, path, fd, profileType);
16655                    fd = null;
16656                    mProfileFd = null;
16657                } else {
16658                    stopProfilerLocked(proc, path, profileType);
16659                    if (fd != null) {
16660                        try {
16661                            fd.close();
16662                        } catch (IOException e) {
16663                        }
16664                    }
16665                }
16666
16667                return true;
16668            }
16669        } catch (RemoteException e) {
16670            throw new IllegalStateException("Process disappeared");
16671        } finally {
16672            if (fd != null) {
16673                try {
16674                    fd.close();
16675                } catch (IOException e) {
16676                }
16677            }
16678        }
16679    }
16680
16681    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16682        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16683                userId, true, true, callName, null);
16684        ProcessRecord proc = null;
16685        try {
16686            int pid = Integer.parseInt(process);
16687            synchronized (mPidsSelfLocked) {
16688                proc = mPidsSelfLocked.get(pid);
16689            }
16690        } catch (NumberFormatException e) {
16691        }
16692
16693        if (proc == null) {
16694            ArrayMap<String, SparseArray<ProcessRecord>> all
16695                    = mProcessNames.getMap();
16696            SparseArray<ProcessRecord> procs = all.get(process);
16697            if (procs != null && procs.size() > 0) {
16698                proc = procs.valueAt(0);
16699                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16700                    for (int i=1; i<procs.size(); i++) {
16701                        ProcessRecord thisProc = procs.valueAt(i);
16702                        if (thisProc.userId == userId) {
16703                            proc = thisProc;
16704                            break;
16705                        }
16706                    }
16707                }
16708            }
16709        }
16710
16711        return proc;
16712    }
16713
16714    public boolean dumpHeap(String process, int userId, boolean managed,
16715            String path, ParcelFileDescriptor fd) throws RemoteException {
16716
16717        try {
16718            synchronized (this) {
16719                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16720                // its own permission (same as profileControl).
16721                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16722                        != PackageManager.PERMISSION_GRANTED) {
16723                    throw new SecurityException("Requires permission "
16724                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16725                }
16726
16727                if (fd == null) {
16728                    throw new IllegalArgumentException("null fd");
16729                }
16730
16731                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16732                if (proc == null || proc.thread == null) {
16733                    throw new IllegalArgumentException("Unknown process: " + process);
16734                }
16735
16736                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16737                if (!isDebuggable) {
16738                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16739                        throw new SecurityException("Process not debuggable: " + proc);
16740                    }
16741                }
16742
16743                proc.thread.dumpHeap(managed, path, fd);
16744                fd = null;
16745                return true;
16746            }
16747        } catch (RemoteException e) {
16748            throw new IllegalStateException("Process disappeared");
16749        } finally {
16750            if (fd != null) {
16751                try {
16752                    fd.close();
16753                } catch (IOException e) {
16754                }
16755            }
16756        }
16757    }
16758
16759    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16760    public void monitor() {
16761        synchronized (this) { }
16762    }
16763
16764    void onCoreSettingsChange(Bundle settings) {
16765        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16766            ProcessRecord processRecord = mLruProcesses.get(i);
16767            try {
16768                if (processRecord.thread != null) {
16769                    processRecord.thread.setCoreSettings(settings);
16770                }
16771            } catch (RemoteException re) {
16772                /* ignore */
16773            }
16774        }
16775    }
16776
16777    // Multi-user methods
16778
16779    /**
16780     * Start user, if its not already running, but don't bring it to foreground.
16781     */
16782    @Override
16783    public boolean startUserInBackground(final int userId) {
16784        return startUser(userId, /* foreground */ false);
16785    }
16786
16787    /**
16788     * Refreshes the list of users related to the current user when either a
16789     * user switch happens or when a new related user is started in the
16790     * background.
16791     */
16792    private void updateCurrentProfileIdsLocked() {
16793        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16794                mCurrentUserId, false /* enabledOnly */);
16795        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16796        for (int i = 0; i < currentProfileIds.length; i++) {
16797            currentProfileIds[i] = profiles.get(i).id;
16798        }
16799        mCurrentProfileIds = currentProfileIds;
16800    }
16801
16802    private Set getProfileIdsLocked(int userId) {
16803        Set userIds = new HashSet<Integer>();
16804        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16805                userId, false /* enabledOnly */);
16806        for (UserInfo user : profiles) {
16807            userIds.add(Integer.valueOf(user.id));
16808        }
16809        return userIds;
16810    }
16811
16812    @Override
16813    public boolean switchUser(final int userId) {
16814        return startUser(userId, /* foregound */ true);
16815    }
16816
16817    private boolean startUser(final int userId, boolean foreground) {
16818        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
16819                != PackageManager.PERMISSION_GRANTED) {
16820            String msg = "Permission Denial: switchUser() from pid="
16821                    + Binder.getCallingPid()
16822                    + ", uid=" + Binder.getCallingUid()
16823                    + " requires " + INTERACT_ACROSS_USERS_FULL;
16824            Slog.w(TAG, msg);
16825            throw new SecurityException(msg);
16826        }
16827
16828        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16829
16830        final long ident = Binder.clearCallingIdentity();
16831        try {
16832            synchronized (this) {
16833                final int oldUserId = mCurrentUserId;
16834                if (oldUserId == userId) {
16835                    return true;
16836                }
16837
16838                mStackSupervisor.setLockTaskModeLocked(null, false);
16839
16840                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16841                if (userInfo == null) {
16842                    Slog.w(TAG, "No user info for user #" + userId);
16843                    return false;
16844                }
16845
16846                if (foreground) {
16847                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16848                            R.anim.screen_user_enter);
16849                }
16850
16851                boolean needStart = false;
16852
16853                // If the user we are switching to is not currently started, then
16854                // we need to start it now.
16855                if (mStartedUsers.get(userId) == null) {
16856                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16857                    updateStartedUserArrayLocked();
16858                    needStart = true;
16859                }
16860
16861                final Integer userIdInt = Integer.valueOf(userId);
16862                mUserLru.remove(userIdInt);
16863                mUserLru.add(userIdInt);
16864
16865                if (foreground) {
16866                    mCurrentUserId = userId;
16867                    updateCurrentProfileIdsLocked();
16868                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16869                    // Once the internal notion of the active user has switched, we lock the device
16870                    // with the option to show the user switcher on the keyguard.
16871                    mWindowManager.lockNow(null);
16872                } else {
16873                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16874                    updateCurrentProfileIdsLocked();
16875                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16876                    mUserLru.remove(currentUserIdInt);
16877                    mUserLru.add(currentUserIdInt);
16878                }
16879
16880                final UserStartedState uss = mStartedUsers.get(userId);
16881
16882                // Make sure user is in the started state.  If it is currently
16883                // stopping, we need to knock that off.
16884                if (uss.mState == UserStartedState.STATE_STOPPING) {
16885                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16886                    // so we can just fairly silently bring the user back from
16887                    // the almost-dead.
16888                    uss.mState = UserStartedState.STATE_RUNNING;
16889                    updateStartedUserArrayLocked();
16890                    needStart = true;
16891                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16892                    // This means ACTION_SHUTDOWN has been sent, so we will
16893                    // need to treat this as a new boot of the user.
16894                    uss.mState = UserStartedState.STATE_BOOTING;
16895                    updateStartedUserArrayLocked();
16896                    needStart = true;
16897                }
16898
16899                if (uss.mState == UserStartedState.STATE_BOOTING) {
16900                    // Booting up a new user, need to tell system services about it.
16901                    // Note that this is on the same handler as scheduling of broadcasts,
16902                    // which is important because it needs to go first.
16903                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
16904                }
16905
16906                if (foreground) {
16907                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId));
16908                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16909                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16910                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16911                            oldUserId, userId, uss));
16912                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16913                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16914                }
16915
16916                if (needStart) {
16917                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16918                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16919                            | Intent.FLAG_RECEIVER_FOREGROUND);
16920                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16921                    broadcastIntentLocked(null, null, intent,
16922                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16923                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16924                }
16925
16926                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16927                    if (userId != UserHandle.USER_OWNER) {
16928                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16929                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16930                        broadcastIntentLocked(null, null, intent, null,
16931                                new IIntentReceiver.Stub() {
16932                                    public void performReceive(Intent intent, int resultCode,
16933                                            String data, Bundle extras, boolean ordered,
16934                                            boolean sticky, int sendingUser) {
16935                                        userInitialized(uss, userId);
16936                                    }
16937                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16938                                true, false, MY_PID, Process.SYSTEM_UID,
16939                                userId);
16940                        uss.initializing = true;
16941                    } else {
16942                        getUserManagerLocked().makeInitialized(userInfo.id);
16943                    }
16944                }
16945
16946                if (foreground) {
16947                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16948                    if (homeInFront) {
16949                        startHomeActivityLocked(userId);
16950                    } else {
16951                        mStackSupervisor.resumeTopActivitiesLocked();
16952                    }
16953                    EventLogTags.writeAmSwitchUser(userId);
16954                    getUserManagerLocked().userForeground(userId);
16955                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16956                } else {
16957                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
16958                }
16959
16960                if (needStart) {
16961                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16962                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16963                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16964                    broadcastIntentLocked(null, null, intent,
16965                            null, new IIntentReceiver.Stub() {
16966                                @Override
16967                                public void performReceive(Intent intent, int resultCode, String data,
16968                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16969                                        throws RemoteException {
16970                                }
16971                            }, 0, null, null,
16972                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16973                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16974                }
16975            }
16976        } finally {
16977            Binder.restoreCallingIdentity(ident);
16978        }
16979
16980        return true;
16981    }
16982
16983    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16984        long ident = Binder.clearCallingIdentity();
16985        try {
16986            Intent intent;
16987            if (oldUserId >= 0) {
16988                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16989                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16990                        | Intent.FLAG_RECEIVER_FOREGROUND);
16991                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16992                broadcastIntentLocked(null, null, intent,
16993                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16994                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16995            }
16996            if (newUserId >= 0) {
16997                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16998                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16999                        | Intent.FLAG_RECEIVER_FOREGROUND);
17000                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
17001                broadcastIntentLocked(null, null, intent,
17002                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17003                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
17004                intent = new Intent(Intent.ACTION_USER_SWITCHED);
17005                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17006                        | Intent.FLAG_RECEIVER_FOREGROUND);
17007                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
17008                broadcastIntentLocked(null, null, intent,
17009                        null, null, 0, null, null,
17010                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
17011                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17012            }
17013        } finally {
17014            Binder.restoreCallingIdentity(ident);
17015        }
17016    }
17017
17018    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
17019            final int newUserId) {
17020        final int N = mUserSwitchObservers.beginBroadcast();
17021        if (N > 0) {
17022            final IRemoteCallback callback = new IRemoteCallback.Stub() {
17023                int mCount = 0;
17024                @Override
17025                public void sendResult(Bundle data) throws RemoteException {
17026                    synchronized (ActivityManagerService.this) {
17027                        if (mCurUserSwitchCallback == this) {
17028                            mCount++;
17029                            if (mCount == N) {
17030                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17031                            }
17032                        }
17033                    }
17034                }
17035            };
17036            synchronized (this) {
17037                uss.switching = true;
17038                mCurUserSwitchCallback = callback;
17039            }
17040            for (int i=0; i<N; i++) {
17041                try {
17042                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17043                            newUserId, callback);
17044                } catch (RemoteException e) {
17045                }
17046            }
17047        } else {
17048            synchronized (this) {
17049                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17050            }
17051        }
17052        mUserSwitchObservers.finishBroadcast();
17053    }
17054
17055    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17056        synchronized (this) {
17057            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17058            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17059        }
17060    }
17061
17062    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17063        mCurUserSwitchCallback = null;
17064        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17065        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17066                oldUserId, newUserId, uss));
17067    }
17068
17069    void userInitialized(UserStartedState uss, int newUserId) {
17070        completeSwitchAndInitalize(uss, newUserId, true, false);
17071    }
17072
17073    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17074        completeSwitchAndInitalize(uss, newUserId, false, true);
17075    }
17076
17077    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17078            boolean clearInitializing, boolean clearSwitching) {
17079        boolean unfrozen = false;
17080        synchronized (this) {
17081            if (clearInitializing) {
17082                uss.initializing = false;
17083                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17084            }
17085            if (clearSwitching) {
17086                uss.switching = false;
17087            }
17088            if (!uss.switching && !uss.initializing) {
17089                mWindowManager.stopFreezingScreen();
17090                unfrozen = true;
17091            }
17092        }
17093        if (unfrozen) {
17094            final int N = mUserSwitchObservers.beginBroadcast();
17095            for (int i=0; i<N; i++) {
17096                try {
17097                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17098                } catch (RemoteException e) {
17099                }
17100            }
17101            mUserSwitchObservers.finishBroadcast();
17102        }
17103    }
17104
17105    void scheduleStartProfilesLocked() {
17106        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17107            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17108                    DateUtils.SECOND_IN_MILLIS);
17109        }
17110    }
17111
17112    void startProfilesLocked() {
17113        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17114        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17115                mCurrentUserId, false /* enabledOnly */);
17116        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17117        for (UserInfo user : profiles) {
17118            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17119                    && user.id != mCurrentUserId) {
17120                toStart.add(user);
17121            }
17122        }
17123        final int n = toStart.size();
17124        int i = 0;
17125        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17126            startUserInBackground(toStart.get(i).id);
17127        }
17128        if (i < n) {
17129            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17130        }
17131    }
17132
17133    void finishUserBoot(UserStartedState uss) {
17134        synchronized (this) {
17135            if (uss.mState == UserStartedState.STATE_BOOTING
17136                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17137                uss.mState = UserStartedState.STATE_RUNNING;
17138                final int userId = uss.mHandle.getIdentifier();
17139                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17140                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17141                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17142                broadcastIntentLocked(null, null, intent,
17143                        null, null, 0, null, null,
17144                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17145                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17146            }
17147        }
17148    }
17149
17150    void finishUserSwitch(UserStartedState uss) {
17151        synchronized (this) {
17152            finishUserBoot(uss);
17153
17154            startProfilesLocked();
17155
17156            int num = mUserLru.size();
17157            int i = 0;
17158            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17159                Integer oldUserId = mUserLru.get(i);
17160                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17161                if (oldUss == null) {
17162                    // Shouldn't happen, but be sane if it does.
17163                    mUserLru.remove(i);
17164                    num--;
17165                    continue;
17166                }
17167                if (oldUss.mState == UserStartedState.STATE_STOPPING
17168                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17169                    // This user is already stopping, doesn't count.
17170                    num--;
17171                    i++;
17172                    continue;
17173                }
17174                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17175                    // Owner and current can't be stopped, but count as running.
17176                    i++;
17177                    continue;
17178                }
17179                // This is a user to be stopped.
17180                stopUserLocked(oldUserId, null);
17181                num--;
17182                i++;
17183            }
17184        }
17185    }
17186
17187    @Override
17188    public int stopUser(final int userId, final IStopUserCallback callback) {
17189        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17190                != PackageManager.PERMISSION_GRANTED) {
17191            String msg = "Permission Denial: switchUser() from pid="
17192                    + Binder.getCallingPid()
17193                    + ", uid=" + Binder.getCallingUid()
17194                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17195            Slog.w(TAG, msg);
17196            throw new SecurityException(msg);
17197        }
17198        if (userId <= 0) {
17199            throw new IllegalArgumentException("Can't stop primary user " + userId);
17200        }
17201        synchronized (this) {
17202            return stopUserLocked(userId, callback);
17203        }
17204    }
17205
17206    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17207        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17208        if (mCurrentUserId == userId) {
17209            return ActivityManager.USER_OP_IS_CURRENT;
17210        }
17211
17212        final UserStartedState uss = mStartedUsers.get(userId);
17213        if (uss == null) {
17214            // User is not started, nothing to do...  but we do need to
17215            // callback if requested.
17216            if (callback != null) {
17217                mHandler.post(new Runnable() {
17218                    @Override
17219                    public void run() {
17220                        try {
17221                            callback.userStopped(userId);
17222                        } catch (RemoteException e) {
17223                        }
17224                    }
17225                });
17226            }
17227            return ActivityManager.USER_OP_SUCCESS;
17228        }
17229
17230        if (callback != null) {
17231            uss.mStopCallbacks.add(callback);
17232        }
17233
17234        if (uss.mState != UserStartedState.STATE_STOPPING
17235                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17236            uss.mState = UserStartedState.STATE_STOPPING;
17237            updateStartedUserArrayLocked();
17238
17239            long ident = Binder.clearCallingIdentity();
17240            try {
17241                // We are going to broadcast ACTION_USER_STOPPING and then
17242                // once that is done send a final ACTION_SHUTDOWN and then
17243                // stop the user.
17244                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17245                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17246                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17247                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17248                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17249                // This is the result receiver for the final shutdown broadcast.
17250                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17251                    @Override
17252                    public void performReceive(Intent intent, int resultCode, String data,
17253                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17254                        finishUserStop(uss);
17255                    }
17256                };
17257                // This is the result receiver for the initial stopping broadcast.
17258                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17259                    @Override
17260                    public void performReceive(Intent intent, int resultCode, String data,
17261                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17262                        // On to the next.
17263                        synchronized (ActivityManagerService.this) {
17264                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17265                                // Whoops, we are being started back up.  Abort, abort!
17266                                return;
17267                            }
17268                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17269                        }
17270                        mSystemServiceManager.stopUser(userId);
17271                        broadcastIntentLocked(null, null, shutdownIntent,
17272                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17273                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17274                    }
17275                };
17276                // Kick things off.
17277                broadcastIntentLocked(null, null, stoppingIntent,
17278                        null, stoppingReceiver, 0, null, null,
17279                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17280                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17281            } finally {
17282                Binder.restoreCallingIdentity(ident);
17283            }
17284        }
17285
17286        return ActivityManager.USER_OP_SUCCESS;
17287    }
17288
17289    void finishUserStop(UserStartedState uss) {
17290        final int userId = uss.mHandle.getIdentifier();
17291        boolean stopped;
17292        ArrayList<IStopUserCallback> callbacks;
17293        synchronized (this) {
17294            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17295            if (mStartedUsers.get(userId) != uss) {
17296                stopped = false;
17297            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17298                stopped = false;
17299            } else {
17300                stopped = true;
17301                // User can no longer run.
17302                mStartedUsers.remove(userId);
17303                mUserLru.remove(Integer.valueOf(userId));
17304                updateStartedUserArrayLocked();
17305
17306                // Clean up all state and processes associated with the user.
17307                // Kill all the processes for the user.
17308                forceStopUserLocked(userId, "finish user");
17309            }
17310        }
17311
17312        for (int i=0; i<callbacks.size(); i++) {
17313            try {
17314                if (stopped) callbacks.get(i).userStopped(userId);
17315                else callbacks.get(i).userStopAborted(userId);
17316            } catch (RemoteException e) {
17317            }
17318        }
17319
17320        if (stopped) {
17321            mSystemServiceManager.cleanupUser(userId);
17322            synchronized (this) {
17323                mStackSupervisor.removeUserLocked(userId);
17324            }
17325        }
17326    }
17327
17328    @Override
17329    public UserInfo getCurrentUser() {
17330        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17331                != PackageManager.PERMISSION_GRANTED) && (
17332                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17333                != PackageManager.PERMISSION_GRANTED)) {
17334            String msg = "Permission Denial: getCurrentUser() from pid="
17335                    + Binder.getCallingPid()
17336                    + ", uid=" + Binder.getCallingUid()
17337                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17338            Slog.w(TAG, msg);
17339            throw new SecurityException(msg);
17340        }
17341        synchronized (this) {
17342            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17343        }
17344    }
17345
17346    int getCurrentUserIdLocked() {
17347        return mCurrentUserId;
17348    }
17349
17350    @Override
17351    public boolean isUserRunning(int userId, boolean orStopped) {
17352        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17353                != PackageManager.PERMISSION_GRANTED) {
17354            String msg = "Permission Denial: isUserRunning() from pid="
17355                    + Binder.getCallingPid()
17356                    + ", uid=" + Binder.getCallingUid()
17357                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17358            Slog.w(TAG, msg);
17359            throw new SecurityException(msg);
17360        }
17361        synchronized (this) {
17362            return isUserRunningLocked(userId, orStopped);
17363        }
17364    }
17365
17366    boolean isUserRunningLocked(int userId, boolean orStopped) {
17367        UserStartedState state = mStartedUsers.get(userId);
17368        if (state == null) {
17369            return false;
17370        }
17371        if (orStopped) {
17372            return true;
17373        }
17374        return state.mState != UserStartedState.STATE_STOPPING
17375                && state.mState != UserStartedState.STATE_SHUTDOWN;
17376    }
17377
17378    @Override
17379    public int[] getRunningUserIds() {
17380        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17381                != PackageManager.PERMISSION_GRANTED) {
17382            String msg = "Permission Denial: isUserRunning() from pid="
17383                    + Binder.getCallingPid()
17384                    + ", uid=" + Binder.getCallingUid()
17385                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17386            Slog.w(TAG, msg);
17387            throw new SecurityException(msg);
17388        }
17389        synchronized (this) {
17390            return mStartedUserArray;
17391        }
17392    }
17393
17394    private void updateStartedUserArrayLocked() {
17395        int num = 0;
17396        for (int i=0; i<mStartedUsers.size();  i++) {
17397            UserStartedState uss = mStartedUsers.valueAt(i);
17398            // This list does not include stopping users.
17399            if (uss.mState != UserStartedState.STATE_STOPPING
17400                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17401                num++;
17402            }
17403        }
17404        mStartedUserArray = new int[num];
17405        num = 0;
17406        for (int i=0; i<mStartedUsers.size();  i++) {
17407            UserStartedState uss = mStartedUsers.valueAt(i);
17408            if (uss.mState != UserStartedState.STATE_STOPPING
17409                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17410                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17411                num++;
17412            }
17413        }
17414    }
17415
17416    @Override
17417    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17418        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17419                != PackageManager.PERMISSION_GRANTED) {
17420            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17421                    + Binder.getCallingPid()
17422                    + ", uid=" + Binder.getCallingUid()
17423                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17424            Slog.w(TAG, msg);
17425            throw new SecurityException(msg);
17426        }
17427
17428        mUserSwitchObservers.register(observer);
17429    }
17430
17431    @Override
17432    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17433        mUserSwitchObservers.unregister(observer);
17434    }
17435
17436    private boolean userExists(int userId) {
17437        if (userId == 0) {
17438            return true;
17439        }
17440        UserManagerService ums = getUserManagerLocked();
17441        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17442    }
17443
17444    int[] getUsersLocked() {
17445        UserManagerService ums = getUserManagerLocked();
17446        return ums != null ? ums.getUserIds() : new int[] { 0 };
17447    }
17448
17449    UserManagerService getUserManagerLocked() {
17450        if (mUserManager == null) {
17451            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17452            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17453        }
17454        return mUserManager;
17455    }
17456
17457    private int applyUserId(int uid, int userId) {
17458        return UserHandle.getUid(userId, uid);
17459    }
17460
17461    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17462        if (info == null) return null;
17463        ApplicationInfo newInfo = new ApplicationInfo(info);
17464        newInfo.uid = applyUserId(info.uid, userId);
17465        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17466                + info.packageName;
17467        return newInfo;
17468    }
17469
17470    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17471        if (aInfo == null
17472                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17473            return aInfo;
17474        }
17475
17476        ActivityInfo info = new ActivityInfo(aInfo);
17477        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17478        return info;
17479    }
17480
17481    private final class LocalService extends ActivityManagerInternal {
17482        @Override
17483        public void goingToSleep() {
17484            ActivityManagerService.this.goingToSleep();
17485        }
17486
17487        @Override
17488        public void wakingUp() {
17489            ActivityManagerService.this.wakingUp();
17490        }
17491    }
17492
17493    /**
17494     * An implementation of IAppTask, that allows an app to manage its own tasks via
17495     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17496     * only the process that calls getAppTasks() can call the AppTask methods.
17497     */
17498    class AppTaskImpl extends IAppTask.Stub {
17499        private int mTaskId;
17500        private int mCallingUid;
17501
17502        public AppTaskImpl(int taskId, int callingUid) {
17503            mTaskId = taskId;
17504            mCallingUid = callingUid;
17505        }
17506
17507        @Override
17508        public void finishAndRemoveTask() {
17509            // Ensure that we are called from the same process that created this AppTask
17510            if (mCallingUid != Binder.getCallingUid()) {
17511                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17512                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17513                return;
17514            }
17515
17516            synchronized (ActivityManagerService.this) {
17517                long origId = Binder.clearCallingIdentity();
17518                try {
17519                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17520                    if (tr != null) {
17521                        // Only kill the process if we are not a new document
17522                        int flags = tr.getBaseIntent().getFlags();
17523                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17524                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17525                        removeTaskByIdLocked(mTaskId,
17526                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17527                    }
17528                } finally {
17529                    Binder.restoreCallingIdentity(origId);
17530                }
17531            }
17532        }
17533
17534        @Override
17535        public ActivityManager.RecentTaskInfo getTaskInfo() {
17536            // Ensure that we are called from the same process that created this AppTask
17537            if (mCallingUid != Binder.getCallingUid()) {
17538                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17539                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17540                return null;
17541            }
17542
17543            synchronized (ActivityManagerService.this) {
17544                long origId = Binder.clearCallingIdentity();
17545                try {
17546                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17547                    if (tr != null) {
17548                        return createRecentTaskInfoFromTaskRecord(tr);
17549                    }
17550                } finally {
17551                    Binder.restoreCallingIdentity(origId);
17552                }
17553                return null;
17554            }
17555        }
17556    }
17557}
17558