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