ActivityManagerService.java revision 76e2a765b495f15a718dc4dfd9d81e9539a7074b
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                                    || st.uid == Process.SYSTEM_UID) {
1837                                // This is definitely an application process; skip it.
1838                                continue;
1839                            }
1840                            synchronized (mPidsSelfLocked) {
1841                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1842                                    // This is one of our own processes; skip it.
1843                                    continue;
1844                                }
1845                            }
1846                            nativeTotalPss += Debug.getPss(st.pid, null);
1847                        }
1848                    }
1849                    memInfo.readMemInfo();
1850                    synchronized (this) {
1851                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1852                                + (SystemClock.uptimeMillis()-start) + "ms");
1853                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1854                                memInfo.getFreeSizeKb(),
1855                                memInfo.getSwapTotalSizeKb()-memInfo.getSwapFreeSizeKb(),
1856                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1857                                        +memInfo.getSlabSizeKb(),
1858                                nativeTotalPss);
1859                    }
1860                }
1861
1862                int i=0, num=0;
1863                long[] tmp = new long[1];
1864                do {
1865                    ProcessRecord proc;
1866                    int procState;
1867                    int pid;
1868                    synchronized (ActivityManagerService.this) {
1869                        if (i >= mPendingPssProcesses.size()) {
1870                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1871                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1872                            mPendingPssProcesses.clear();
1873                            return;
1874                        }
1875                        proc = mPendingPssProcesses.get(i);
1876                        procState = proc.pssProcState;
1877                        if (proc.thread != null && procState == proc.setProcState) {
1878                            pid = proc.pid;
1879                        } else {
1880                            proc = null;
1881                            pid = 0;
1882                        }
1883                        i++;
1884                    }
1885                    if (proc != null) {
1886                        long pss = Debug.getPss(pid, tmp);
1887                        synchronized (ActivityManagerService.this) {
1888                            if (proc.thread != null && proc.setProcState == procState
1889                                    && proc.pid == pid) {
1890                                num++;
1891                                proc.lastPssTime = SystemClock.uptimeMillis();
1892                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1893                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1894                                        + ": " + pss + " lastPss=" + proc.lastPss
1895                                        + " state=" + ProcessList.makeProcStateString(procState));
1896                                if (proc.initialIdlePss == 0) {
1897                                    proc.initialIdlePss = pss;
1898                                }
1899                                proc.lastPss = pss;
1900                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1901                                    proc.lastCachedPss = pss;
1902                                }
1903                            }
1904                        }
1905                    }
1906                } while (true);
1907            }
1908            }
1909        }
1910    };
1911
1912    /**
1913     * Monitor for package changes and update our internal state.
1914     */
1915    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1916        @Override
1917        public void onPackageRemoved(String packageName, int uid) {
1918            // Remove all tasks with activities in the specified package from the list of recent tasks
1919            synchronized (ActivityManagerService.this) {
1920                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1921                    TaskRecord tr = mRecentTasks.get(i);
1922                    ComponentName cn = tr.intent.getComponent();
1923                    if (cn != null && cn.getPackageName().equals(packageName)) {
1924                        // If the package name matches, remove the task and kill the process
1925                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1926                    }
1927                }
1928            }
1929        }
1930
1931        @Override
1932        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1933            onPackageModified(packageName);
1934            return true;
1935        }
1936
1937        @Override
1938        public void onPackageModified(String packageName) {
1939            final PackageManager pm = mContext.getPackageManager();
1940            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1941                    new ArrayList<Pair<Intent, Integer>>();
1942            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1943            // Copy the list of recent tasks so that we don't hold onto the lock on
1944            // ActivityManagerService for long periods while checking if components exist.
1945            synchronized (ActivityManagerService.this) {
1946                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1947                    TaskRecord tr = mRecentTasks.get(i);
1948                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1949                }
1950            }
1951            // Check the recent tasks and filter out all tasks with components that no longer exist.
1952            Intent tmpI = new Intent();
1953            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1954                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1955                ComponentName cn = p.first.getComponent();
1956                if (cn != null && cn.getPackageName().equals(packageName)) {
1957                    try {
1958                        // Add the task to the list to remove if the component no longer exists
1959                        tmpI.setComponent(cn);
1960                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1961                            tasksToRemove.add(p.second);
1962                        }
1963                    } catch (Exception e) {}
1964                }
1965            }
1966            // Prune all the tasks with removed components from the list of recent tasks
1967            synchronized (ActivityManagerService.this) {
1968                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1969                    // Remove the task but don't kill the process (since other components in that
1970                    // package may still be running and in the background)
1971                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1972                }
1973            }
1974        }
1975
1976        @Override
1977        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1978            // Force stop the specified packages
1979            if (packages != null) {
1980                for (String pkg : packages) {
1981                    synchronized (ActivityManagerService.this) {
1982                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
1983                                "finished booting")) {
1984                            return true;
1985                        }
1986                    }
1987                }
1988            }
1989            return false;
1990        }
1991    };
1992
1993    public void setSystemProcess() {
1994        try {
1995            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1996            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1997            ServiceManager.addService("meminfo", new MemBinder(this));
1998            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1999            ServiceManager.addService("dbinfo", new DbBinder(this));
2000            if (MONITOR_CPU_USAGE) {
2001                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2002            }
2003            ServiceManager.addService("permission", new PermissionController(this));
2004
2005            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2006                    "android", STOCK_PM_FLAGS);
2007            mSystemThread.installSystemApplicationInfo(info);
2008
2009            synchronized (this) {
2010                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
2011                app.persistent = true;
2012                app.pid = MY_PID;
2013                app.maxAdj = ProcessList.SYSTEM_ADJ;
2014                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2015                mProcessNames.put(app.processName, app.uid, app);
2016                synchronized (mPidsSelfLocked) {
2017                    mPidsSelfLocked.put(app.pid, app);
2018                }
2019                updateLruProcessLocked(app, false, null);
2020                updateOomAdjLocked();
2021            }
2022        } catch (PackageManager.NameNotFoundException e) {
2023            throw new RuntimeException(
2024                    "Unable to find android system package", e);
2025        }
2026    }
2027
2028    public void setWindowManager(WindowManagerService wm) {
2029        mWindowManager = wm;
2030        mStackSupervisor.setWindowManager(wm);
2031    }
2032
2033    public void startObservingNativeCrashes() {
2034        final NativeCrashListener ncl = new NativeCrashListener(this);
2035        ncl.start();
2036    }
2037
2038    public IAppOpsService getAppOpsService() {
2039        return mAppOpsService;
2040    }
2041
2042    static class MemBinder extends Binder {
2043        ActivityManagerService mActivityManagerService;
2044        MemBinder(ActivityManagerService activityManagerService) {
2045            mActivityManagerService = activityManagerService;
2046        }
2047
2048        @Override
2049        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2050            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2051                    != PackageManager.PERMISSION_GRANTED) {
2052                pw.println("Permission Denial: can't dump meminfo from from pid="
2053                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2054                        + " without permission " + android.Manifest.permission.DUMP);
2055                return;
2056            }
2057
2058            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2059        }
2060    }
2061
2062    static class GraphicsBinder extends Binder {
2063        ActivityManagerService mActivityManagerService;
2064        GraphicsBinder(ActivityManagerService activityManagerService) {
2065            mActivityManagerService = activityManagerService;
2066        }
2067
2068        @Override
2069        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2070            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2071                    != PackageManager.PERMISSION_GRANTED) {
2072                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2073                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2074                        + " without permission " + android.Manifest.permission.DUMP);
2075                return;
2076            }
2077
2078            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2079        }
2080    }
2081
2082    static class DbBinder extends Binder {
2083        ActivityManagerService mActivityManagerService;
2084        DbBinder(ActivityManagerService activityManagerService) {
2085            mActivityManagerService = activityManagerService;
2086        }
2087
2088        @Override
2089        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2090            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2091                    != PackageManager.PERMISSION_GRANTED) {
2092                pw.println("Permission Denial: can't dump dbinfo from from pid="
2093                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2094                        + " without permission " + android.Manifest.permission.DUMP);
2095                return;
2096            }
2097
2098            mActivityManagerService.dumpDbInfo(fd, pw, args);
2099        }
2100    }
2101
2102    static class CpuBinder extends Binder {
2103        ActivityManagerService mActivityManagerService;
2104        CpuBinder(ActivityManagerService activityManagerService) {
2105            mActivityManagerService = activityManagerService;
2106        }
2107
2108        @Override
2109        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2110            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2111                    != PackageManager.PERMISSION_GRANTED) {
2112                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2113                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2114                        + " without permission " + android.Manifest.permission.DUMP);
2115                return;
2116            }
2117
2118            synchronized (mActivityManagerService.mProcessCpuThread) {
2119                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2120                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2121                        SystemClock.uptimeMillis()));
2122            }
2123        }
2124    }
2125
2126    public static final class Lifecycle extends SystemService {
2127        private final ActivityManagerService mService;
2128
2129        public Lifecycle(Context context) {
2130            super(context);
2131            mService = new ActivityManagerService(context);
2132        }
2133
2134        @Override
2135        public void onStart() {
2136            mService.start();
2137        }
2138
2139        public ActivityManagerService getService() {
2140            return mService;
2141        }
2142    }
2143
2144    // Note: This method is invoked on the main thread but may need to attach various
2145    // handlers to other threads.  So take care to be explicit about the looper.
2146    public ActivityManagerService(Context systemContext) {
2147        mContext = systemContext;
2148        mFactoryTest = FactoryTest.getMode();
2149        mSystemThread = ActivityThread.currentActivityThread();
2150
2151        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2152
2153        mHandlerThread = new ServiceThread(TAG,
2154                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2155        mHandlerThread.start();
2156        mHandler = new MainHandler(mHandlerThread.getLooper());
2157
2158        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2159                "foreground", BROADCAST_FG_TIMEOUT, false);
2160        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2161                "background", BROADCAST_BG_TIMEOUT, true);
2162        mBroadcastQueues[0] = mFgBroadcastQueue;
2163        mBroadcastQueues[1] = mBgBroadcastQueue;
2164
2165        mServices = new ActiveServices(this);
2166        mProviderMap = new ProviderMap(this);
2167
2168        // TODO: Move creation of battery stats service outside of activity manager service.
2169        File dataDir = Environment.getDataDirectory();
2170        File systemDir = new File(dataDir, "system");
2171        systemDir.mkdirs();
2172        mBatteryStatsService = new BatteryStatsService(new File(
2173                systemDir, "batterystats.bin").toString(), mHandler);
2174        mBatteryStatsService.getActiveStatistics().readLocked();
2175        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2176        mOnBattery = DEBUG_POWER ? true
2177                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2178        mBatteryStatsService.getActiveStatistics().setCallback(this);
2179
2180        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2181
2182        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
2183        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2184
2185        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2186
2187        // User 0 is the first and only user that runs at boot.
2188        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2189        mUserLru.add(Integer.valueOf(0));
2190        updateStartedUserArrayLocked();
2191
2192        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2193            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2194
2195        mConfiguration.setToDefaults();
2196        mConfiguration.setLocale(Locale.getDefault());
2197
2198        mConfigurationSeq = mConfiguration.seq = 1;
2199        mProcessCpuTracker.init();
2200
2201        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2202        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2203        mStackSupervisor = new ActivityStackSupervisor(this);
2204        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2205
2206        mProcessCpuThread = new Thread("CpuTracker") {
2207            @Override
2208            public void run() {
2209                while (true) {
2210                    try {
2211                        try {
2212                            synchronized(this) {
2213                                final long now = SystemClock.uptimeMillis();
2214                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2215                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2216                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2217                                //        + ", write delay=" + nextWriteDelay);
2218                                if (nextWriteDelay < nextCpuDelay) {
2219                                    nextCpuDelay = nextWriteDelay;
2220                                }
2221                                if (nextCpuDelay > 0) {
2222                                    mProcessCpuMutexFree.set(true);
2223                                    this.wait(nextCpuDelay);
2224                                }
2225                            }
2226                        } catch (InterruptedException e) {
2227                        }
2228                        updateCpuStatsNow();
2229                    } catch (Exception e) {
2230                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2231                    }
2232                }
2233            }
2234        };
2235
2236        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2237
2238        Watchdog.getInstance().addMonitor(this);
2239        Watchdog.getInstance().addThread(mHandler);
2240    }
2241
2242    public void setSystemServiceManager(SystemServiceManager mgr) {
2243        mSystemServiceManager = mgr;
2244    }
2245
2246    private void start() {
2247        mProcessCpuThread.start();
2248
2249        mBatteryStatsService.publish(mContext);
2250        mUsageStatsService.publish(mContext);
2251        mAppOpsService.publish(mContext);
2252        Slog.d("AppOps", "AppOpsService published");
2253        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2254    }
2255
2256    public void initPowerManagement() {
2257        mStackSupervisor.initPowerManagement();
2258        mBatteryStatsService.initPowerManagement();
2259    }
2260
2261    @Override
2262    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2263            throws RemoteException {
2264        if (code == SYSPROPS_TRANSACTION) {
2265            // We need to tell all apps about the system property change.
2266            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2267            synchronized(this) {
2268                final int NP = mProcessNames.getMap().size();
2269                for (int ip=0; ip<NP; ip++) {
2270                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2271                    final int NA = apps.size();
2272                    for (int ia=0; ia<NA; ia++) {
2273                        ProcessRecord app = apps.valueAt(ia);
2274                        if (app.thread != null) {
2275                            procs.add(app.thread.asBinder());
2276                        }
2277                    }
2278                }
2279            }
2280
2281            int N = procs.size();
2282            for (int i=0; i<N; i++) {
2283                Parcel data2 = Parcel.obtain();
2284                try {
2285                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2286                } catch (RemoteException e) {
2287                }
2288                data2.recycle();
2289            }
2290        }
2291        try {
2292            return super.onTransact(code, data, reply, flags);
2293        } catch (RuntimeException e) {
2294            // The activity manager only throws security exceptions, so let's
2295            // log all others.
2296            if (!(e instanceof SecurityException)) {
2297                Slog.wtf(TAG, "Activity Manager Crash", e);
2298            }
2299            throw e;
2300        }
2301    }
2302
2303    void updateCpuStats() {
2304        final long now = SystemClock.uptimeMillis();
2305        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2306            return;
2307        }
2308        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2309            synchronized (mProcessCpuThread) {
2310                mProcessCpuThread.notify();
2311            }
2312        }
2313    }
2314
2315    void updateCpuStatsNow() {
2316        synchronized (mProcessCpuThread) {
2317            mProcessCpuMutexFree.set(false);
2318            final long now = SystemClock.uptimeMillis();
2319            boolean haveNewCpuStats = false;
2320
2321            if (MONITOR_CPU_USAGE &&
2322                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2323                mLastCpuTime.set(now);
2324                haveNewCpuStats = true;
2325                mProcessCpuTracker.update();
2326                //Slog.i(TAG, mProcessCpu.printCurrentState());
2327                //Slog.i(TAG, "Total CPU usage: "
2328                //        + mProcessCpu.getTotalCpuPercent() + "%");
2329
2330                // Slog the cpu usage if the property is set.
2331                if ("true".equals(SystemProperties.get("events.cpu"))) {
2332                    int user = mProcessCpuTracker.getLastUserTime();
2333                    int system = mProcessCpuTracker.getLastSystemTime();
2334                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2335                    int irq = mProcessCpuTracker.getLastIrqTime();
2336                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2337                    int idle = mProcessCpuTracker.getLastIdleTime();
2338
2339                    int total = user + system + iowait + irq + softIrq + idle;
2340                    if (total == 0) total = 1;
2341
2342                    EventLog.writeEvent(EventLogTags.CPU,
2343                            ((user+system+iowait+irq+softIrq) * 100) / total,
2344                            (user * 100) / total,
2345                            (system * 100) / total,
2346                            (iowait * 100) / total,
2347                            (irq * 100) / total,
2348                            (softIrq * 100) / total);
2349                }
2350            }
2351
2352            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2353            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2354            synchronized(bstats) {
2355                synchronized(mPidsSelfLocked) {
2356                    if (haveNewCpuStats) {
2357                        if (mOnBattery) {
2358                            int perc = bstats.startAddingCpuLocked();
2359                            int totalUTime = 0;
2360                            int totalSTime = 0;
2361                            final int N = mProcessCpuTracker.countStats();
2362                            for (int i=0; i<N; i++) {
2363                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2364                                if (!st.working) {
2365                                    continue;
2366                                }
2367                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2368                                int otherUTime = (st.rel_utime*perc)/100;
2369                                int otherSTime = (st.rel_stime*perc)/100;
2370                                totalUTime += otherUTime;
2371                                totalSTime += otherSTime;
2372                                if (pr != null) {
2373                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2374                                    if (ps == null || !ps.isActive()) {
2375                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2376                                                pr.info.uid, pr.processName);
2377                                    }
2378                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2379                                            st.rel_stime-otherSTime);
2380                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2381                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2382                                } else {
2383                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2384                                    if (ps == null || !ps.isActive()) {
2385                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2386                                                bstats.mapUid(st.uid), st.name);
2387                                    }
2388                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2389                                            st.rel_stime-otherSTime);
2390                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2391                                }
2392                            }
2393                            bstats.finishAddingCpuLocked(perc, totalUTime,
2394                                    totalSTime, cpuSpeedTimes);
2395                        }
2396                    }
2397                }
2398
2399                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2400                    mLastWriteTime = now;
2401                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2402                }
2403            }
2404        }
2405    }
2406
2407    @Override
2408    public void batteryNeedsCpuUpdate() {
2409        updateCpuStatsNow();
2410    }
2411
2412    @Override
2413    public void batteryPowerChanged(boolean onBattery) {
2414        // When plugging in, update the CPU stats first before changing
2415        // the plug state.
2416        updateCpuStatsNow();
2417        synchronized (this) {
2418            synchronized(mPidsSelfLocked) {
2419                mOnBattery = DEBUG_POWER ? true : onBattery;
2420            }
2421        }
2422    }
2423
2424    /**
2425     * Initialize the application bind args. These are passed to each
2426     * process when the bindApplication() IPC is sent to the process. They're
2427     * lazily setup to make sure the services are running when they're asked for.
2428     */
2429    private HashMap<String, IBinder> getCommonServicesLocked() {
2430        if (mAppBindArgs == null) {
2431            mAppBindArgs = new HashMap<String, IBinder>();
2432
2433            // Setup the application init args
2434            mAppBindArgs.put("package", ServiceManager.getService("package"));
2435            mAppBindArgs.put("window", ServiceManager.getService("window"));
2436            mAppBindArgs.put(Context.ALARM_SERVICE,
2437                    ServiceManager.getService(Context.ALARM_SERVICE));
2438        }
2439        return mAppBindArgs;
2440    }
2441
2442    final void setFocusedActivityLocked(ActivityRecord r) {
2443        if (mFocusedActivity != r) {
2444            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2445            mFocusedActivity = r;
2446            if (r.task != null && r.task.voiceInteractor != null) {
2447                startRunningVoiceLocked();
2448            } else {
2449                finishRunningVoiceLocked();
2450            }
2451            mStackSupervisor.setFocusedStack(r);
2452            if (r != null) {
2453                mWindowManager.setFocusedApp(r.appToken, true);
2454            }
2455            applyUpdateLockStateLocked(r);
2456        }
2457    }
2458
2459    final void clearFocusedActivity(ActivityRecord r) {
2460        if (mFocusedActivity == r) {
2461            mFocusedActivity = null;
2462        }
2463    }
2464
2465    @Override
2466    public void setFocusedStack(int stackId) {
2467        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2468        synchronized (ActivityManagerService.this) {
2469            ActivityStack stack = mStackSupervisor.getStack(stackId);
2470            if (stack != null) {
2471                ActivityRecord r = stack.topRunningActivityLocked(null);
2472                if (r != null) {
2473                    setFocusedActivityLocked(r);
2474                }
2475            }
2476        }
2477    }
2478
2479    @Override
2480    public void notifyActivityDrawn(IBinder token) {
2481        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2482        synchronized (this) {
2483            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2484            if (r != null) {
2485                r.task.stack.notifyActivityDrawnLocked(r);
2486            }
2487        }
2488    }
2489
2490    final void applyUpdateLockStateLocked(ActivityRecord r) {
2491        // Modifications to the UpdateLock state are done on our handler, outside
2492        // the activity manager's locks.  The new state is determined based on the
2493        // state *now* of the relevant activity record.  The object is passed to
2494        // the handler solely for logging detail, not to be consulted/modified.
2495        final boolean nextState = r != null && r.immersive;
2496        mHandler.sendMessage(
2497                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2498    }
2499
2500    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2501        Message msg = Message.obtain();
2502        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2503        msg.obj = r.task.askedCompatMode ? null : r;
2504        mHandler.sendMessage(msg);
2505    }
2506
2507    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2508            String what, Object obj, ProcessRecord srcApp) {
2509        app.lastActivityTime = now;
2510
2511        if (app.activities.size() > 0) {
2512            // Don't want to touch dependent processes that are hosting activities.
2513            return index;
2514        }
2515
2516        int lrui = mLruProcesses.lastIndexOf(app);
2517        if (lrui < 0) {
2518            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2519                    + what + " " + obj + " from " + srcApp);
2520            return index;
2521        }
2522
2523        if (lrui >= index) {
2524            // Don't want to cause this to move dependent processes *back* in the
2525            // list as if they were less frequently used.
2526            return index;
2527        }
2528
2529        if (lrui >= mLruProcessActivityStart) {
2530            // Don't want to touch dependent processes that are hosting activities.
2531            return index;
2532        }
2533
2534        mLruProcesses.remove(lrui);
2535        if (index > 0) {
2536            index--;
2537        }
2538        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2539                + " in LRU list: " + app);
2540        mLruProcesses.add(index, app);
2541        return index;
2542    }
2543
2544    final void removeLruProcessLocked(ProcessRecord app) {
2545        int lrui = mLruProcesses.lastIndexOf(app);
2546        if (lrui >= 0) {
2547            if (lrui <= mLruProcessActivityStart) {
2548                mLruProcessActivityStart--;
2549            }
2550            if (lrui <= mLruProcessServiceStart) {
2551                mLruProcessServiceStart--;
2552            }
2553            mLruProcesses.remove(lrui);
2554        }
2555    }
2556
2557    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2558            ProcessRecord client) {
2559        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2560                || app.treatLikeActivity;
2561        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2562        if (!activityChange && hasActivity) {
2563            // The process has activities, so we are only allowing activity-based adjustments
2564            // to move it.  It should be kept in the front of the list with other
2565            // processes that have activities, and we don't want those to change their
2566            // order except due to activity operations.
2567            return;
2568        }
2569
2570        mLruSeq++;
2571        final long now = SystemClock.uptimeMillis();
2572        app.lastActivityTime = now;
2573
2574        // First a quick reject: if the app is already at the position we will
2575        // put it, then there is nothing to do.
2576        if (hasActivity) {
2577            final int N = mLruProcesses.size();
2578            if (N > 0 && mLruProcesses.get(N-1) == app) {
2579                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2580                return;
2581            }
2582        } else {
2583            if (mLruProcessServiceStart > 0
2584                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2585                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2586                return;
2587            }
2588        }
2589
2590        int lrui = mLruProcesses.lastIndexOf(app);
2591
2592        if (app.persistent && lrui >= 0) {
2593            // We don't care about the position of persistent processes, as long as
2594            // they are in the list.
2595            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2596            return;
2597        }
2598
2599        /* In progress: compute new position first, so we can avoid doing work
2600           if the process is not actually going to move.  Not yet working.
2601        int addIndex;
2602        int nextIndex;
2603        boolean inActivity = false, inService = false;
2604        if (hasActivity) {
2605            // Process has activities, put it at the very tipsy-top.
2606            addIndex = mLruProcesses.size();
2607            nextIndex = mLruProcessServiceStart;
2608            inActivity = true;
2609        } else if (hasService) {
2610            // Process has services, put it at the top of the service list.
2611            addIndex = mLruProcessActivityStart;
2612            nextIndex = mLruProcessServiceStart;
2613            inActivity = true;
2614            inService = true;
2615        } else  {
2616            // Process not otherwise of interest, it goes to the top of the non-service area.
2617            addIndex = mLruProcessServiceStart;
2618            if (client != null) {
2619                int clientIndex = mLruProcesses.lastIndexOf(client);
2620                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2621                        + app);
2622                if (clientIndex >= 0 && addIndex > clientIndex) {
2623                    addIndex = clientIndex;
2624                }
2625            }
2626            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2627        }
2628
2629        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2630                + mLruProcessActivityStart + "): " + app);
2631        */
2632
2633        if (lrui >= 0) {
2634            if (lrui < mLruProcessActivityStart) {
2635                mLruProcessActivityStart--;
2636            }
2637            if (lrui < mLruProcessServiceStart) {
2638                mLruProcessServiceStart--;
2639            }
2640            /*
2641            if (addIndex > lrui) {
2642                addIndex--;
2643            }
2644            if (nextIndex > lrui) {
2645                nextIndex--;
2646            }
2647            */
2648            mLruProcesses.remove(lrui);
2649        }
2650
2651        /*
2652        mLruProcesses.add(addIndex, app);
2653        if (inActivity) {
2654            mLruProcessActivityStart++;
2655        }
2656        if (inService) {
2657            mLruProcessActivityStart++;
2658        }
2659        */
2660
2661        int nextIndex;
2662        if (hasActivity) {
2663            final int N = mLruProcesses.size();
2664            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2665                // Process doesn't have activities, but has clients with
2666                // activities...  move it up, but one below the top (the top
2667                // should always have a real activity).
2668                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2669                mLruProcesses.add(N-1, app);
2670                // To keep it from spamming the LRU list (by making a bunch of clients),
2671                // we will push down any other entries owned by the app.
2672                final int uid = app.info.uid;
2673                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2674                    ProcessRecord subProc = mLruProcesses.get(i);
2675                    if (subProc.info.uid == uid) {
2676                        // We want to push this one down the list.  If the process after
2677                        // it is for the same uid, however, don't do so, because we don't
2678                        // want them internally to be re-ordered.
2679                        if (mLruProcesses.get(i-1).info.uid != uid) {
2680                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2681                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2682                            ProcessRecord tmp = mLruProcesses.get(i);
2683                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2684                            mLruProcesses.set(i-1, tmp);
2685                            i--;
2686                        }
2687                    } else {
2688                        // A gap, we can stop here.
2689                        break;
2690                    }
2691                }
2692            } else {
2693                // Process has activities, put it at the very tipsy-top.
2694                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2695                mLruProcesses.add(app);
2696            }
2697            nextIndex = mLruProcessServiceStart;
2698        } else if (hasService) {
2699            // Process has services, put it at the top of the service list.
2700            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2701            mLruProcesses.add(mLruProcessActivityStart, app);
2702            nextIndex = mLruProcessServiceStart;
2703            mLruProcessActivityStart++;
2704        } else  {
2705            // Process not otherwise of interest, it goes to the top of the non-service area.
2706            int index = mLruProcessServiceStart;
2707            if (client != null) {
2708                // If there is a client, don't allow the process to be moved up higher
2709                // in the list than that client.
2710                int clientIndex = mLruProcesses.lastIndexOf(client);
2711                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2712                        + " when updating " + app);
2713                if (clientIndex <= lrui) {
2714                    // Don't allow the client index restriction to push it down farther in the
2715                    // list than it already is.
2716                    clientIndex = lrui;
2717                }
2718                if (clientIndex >= 0 && index > clientIndex) {
2719                    index = clientIndex;
2720                }
2721            }
2722            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2723            mLruProcesses.add(index, app);
2724            nextIndex = index-1;
2725            mLruProcessActivityStart++;
2726            mLruProcessServiceStart++;
2727        }
2728
2729        // If the app is currently using a content provider or service,
2730        // bump those processes as well.
2731        for (int j=app.connections.size()-1; j>=0; j--) {
2732            ConnectionRecord cr = app.connections.valueAt(j);
2733            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2734                    && cr.binding.service.app != null
2735                    && cr.binding.service.app.lruSeq != mLruSeq
2736                    && !cr.binding.service.app.persistent) {
2737                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2738                        "service connection", cr, app);
2739            }
2740        }
2741        for (int j=app.conProviders.size()-1; j>=0; j--) {
2742            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2743            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2744                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2745                        "provider reference", cpr, app);
2746            }
2747        }
2748    }
2749
2750    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2751        if (uid == Process.SYSTEM_UID) {
2752            // The system gets to run in any process.  If there are multiple
2753            // processes with the same uid, just pick the first (this
2754            // should never happen).
2755            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2756            if (procs == null) return null;
2757            final int N = procs.size();
2758            for (int i = 0; i < N; i++) {
2759                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2760            }
2761        }
2762        ProcessRecord proc = mProcessNames.get(processName, uid);
2763        if (false && proc != null && !keepIfLarge
2764                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2765                && proc.lastCachedPss >= 4000) {
2766            // Turn this condition on to cause killing to happen regularly, for testing.
2767            if (proc.baseProcessTracker != null) {
2768                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2769            }
2770            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2771                    + "k from cached");
2772        } else if (proc != null && !keepIfLarge
2773                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2774                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2775            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2776            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2777                if (proc.baseProcessTracker != null) {
2778                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2779                }
2780                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2781                        + "k from cached");
2782            }
2783        }
2784        return proc;
2785    }
2786
2787    void ensurePackageDexOpt(String packageName) {
2788        IPackageManager pm = AppGlobals.getPackageManager();
2789        try {
2790            if (pm.performDexOpt(packageName)) {
2791                mDidDexOpt = true;
2792            }
2793        } catch (RemoteException e) {
2794        }
2795    }
2796
2797    boolean isNextTransitionForward() {
2798        int transit = mWindowManager.getPendingAppTransition();
2799        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2800                || transit == AppTransition.TRANSIT_TASK_OPEN
2801                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2802    }
2803
2804    final ProcessRecord startProcessLocked(String processName,
2805            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2806            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2807            boolean isolated, boolean keepIfLarge) {
2808        ProcessRecord app;
2809        if (!isolated) {
2810            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2811        } else {
2812            // If this is an isolated process, it can't re-use an existing process.
2813            app = null;
2814        }
2815        // We don't have to do anything more if:
2816        // (1) There is an existing application record; and
2817        // (2) The caller doesn't think it is dead, OR there is no thread
2818        //     object attached to it so we know it couldn't have crashed; and
2819        // (3) There is a pid assigned to it, so it is either starting or
2820        //     already running.
2821        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2822                + " app=" + app + " knownToBeDead=" + knownToBeDead
2823                + " thread=" + (app != null ? app.thread : null)
2824                + " pid=" + (app != null ? app.pid : -1));
2825        if (app != null && app.pid > 0) {
2826            if (!knownToBeDead || app.thread == null) {
2827                // We already have the app running, or are waiting for it to
2828                // come up (we have a pid but not yet its thread), so keep it.
2829                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2830                // If this is a new package in the process, add the package to the list
2831                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2832                return app;
2833            }
2834
2835            // An application record is attached to a previous process,
2836            // clean it up now.
2837            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2838            handleAppDiedLocked(app, true, true);
2839        }
2840
2841        String hostingNameStr = hostingName != null
2842                ? hostingName.flattenToShortString() : null;
2843
2844        if (!isolated) {
2845            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2846                // If we are in the background, then check to see if this process
2847                // is bad.  If so, we will just silently fail.
2848                if (mBadProcesses.get(info.processName, info.uid) != null) {
2849                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2850                            + "/" + info.processName);
2851                    return null;
2852                }
2853            } else {
2854                // When the user is explicitly starting a process, then clear its
2855                // crash count so that we won't make it bad until they see at
2856                // least one crash dialog again, and make the process good again
2857                // if it had been bad.
2858                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2859                        + "/" + info.processName);
2860                mProcessCrashTimes.remove(info.processName, info.uid);
2861                if (mBadProcesses.get(info.processName, info.uid) != null) {
2862                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2863                            UserHandle.getUserId(info.uid), info.uid,
2864                            info.processName);
2865                    mBadProcesses.remove(info.processName, info.uid);
2866                    if (app != null) {
2867                        app.bad = false;
2868                    }
2869                }
2870            }
2871        }
2872
2873        if (app == null) {
2874            app = newProcessRecordLocked(info, processName, isolated);
2875            if (app == null) {
2876                Slog.w(TAG, "Failed making new process record for "
2877                        + processName + "/" + info.uid + " isolated=" + isolated);
2878                return null;
2879            }
2880            mProcessNames.put(processName, app.uid, app);
2881            if (isolated) {
2882                mIsolatedProcesses.put(app.uid, app);
2883            }
2884        } else {
2885            // If this is a new package in the process, add the package to the list
2886            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2887        }
2888
2889        // If the system is not ready yet, then hold off on starting this
2890        // process until it is.
2891        if (!mProcessesReady
2892                && !isAllowedWhileBooting(info)
2893                && !allowWhileBooting) {
2894            if (!mProcessesOnHold.contains(app)) {
2895                mProcessesOnHold.add(app);
2896            }
2897            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2898            return app;
2899        }
2900
2901        startProcessLocked(app, hostingType, hostingNameStr, null /* ABI override */);
2902        return (app.pid != 0) ? app : null;
2903    }
2904
2905    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2906        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2907    }
2908
2909    private final void startProcessLocked(ProcessRecord app,
2910            String hostingType, String hostingNameStr, String abiOverride) {
2911        if (app.pid > 0 && app.pid != MY_PID) {
2912            synchronized (mPidsSelfLocked) {
2913                mPidsSelfLocked.remove(app.pid);
2914                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2915            }
2916            app.setPid(0);
2917        }
2918
2919        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2920                "startProcessLocked removing on hold: " + app);
2921        mProcessesOnHold.remove(app);
2922
2923        updateCpuStats();
2924
2925        try {
2926            int uid = app.uid;
2927
2928            int[] gids = null;
2929            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2930            if (!app.isolated) {
2931                int[] permGids = null;
2932                try {
2933                    final PackageManager pm = mContext.getPackageManager();
2934                    permGids = pm.getPackageGids(app.info.packageName);
2935
2936                    if (Environment.isExternalStorageEmulated()) {
2937                        if (pm.checkPermission(
2938                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2939                                app.info.packageName) == PERMISSION_GRANTED) {
2940                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2941                        } else {
2942                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2943                        }
2944                    }
2945                } catch (PackageManager.NameNotFoundException e) {
2946                    Slog.w(TAG, "Unable to retrieve gids", e);
2947                }
2948
2949                /*
2950                 * Add shared application and profile GIDs so applications can share some
2951                 * resources like shared libraries and access user-wide resources
2952                 */
2953                if (permGids == null) {
2954                    gids = new int[2];
2955                } else {
2956                    gids = new int[permGids.length + 2];
2957                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2958                }
2959                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2960                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2961            }
2962            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2963                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2964                        && mTopComponent != null
2965                        && app.processName.equals(mTopComponent.getPackageName())) {
2966                    uid = 0;
2967                }
2968                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2969                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2970                    uid = 0;
2971                }
2972            }
2973            int debugFlags = 0;
2974            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2975                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2976                // Also turn on CheckJNI for debuggable apps. It's quite
2977                // awkward to turn on otherwise.
2978                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2979            }
2980            // Run the app in safe mode if its manifest requests so or the
2981            // system is booted in safe mode.
2982            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2983                mSafeMode == true) {
2984                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2985            }
2986            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2987                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2988            }
2989            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2990                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2991            }
2992            if ("1".equals(SystemProperties.get("debug.assert"))) {
2993                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2994            }
2995
2996            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.cpuAbi;
2997            if (requiredAbi == null) {
2998                requiredAbi = Build.SUPPORTED_ABIS[0];
2999            }
3000
3001            // Start the process.  It will either succeed and return a result containing
3002            // the PID of the new process, or else throw a RuntimeException.
3003            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
3004                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3005                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
3006
3007            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
3008            synchronized (bs) {
3009                if (bs.isOnBattery()) {
3010                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
3011                }
3012            }
3013
3014            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3015                    UserHandle.getUserId(uid), startResult.pid, uid,
3016                    app.processName, hostingType,
3017                    hostingNameStr != null ? hostingNameStr : "");
3018
3019            if (app.persistent) {
3020                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3021            }
3022
3023            StringBuilder buf = mStringBuilder;
3024            buf.setLength(0);
3025            buf.append("Start proc ");
3026            buf.append(app.processName);
3027            buf.append(" for ");
3028            buf.append(hostingType);
3029            if (hostingNameStr != null) {
3030                buf.append(" ");
3031                buf.append(hostingNameStr);
3032            }
3033            buf.append(": pid=");
3034            buf.append(startResult.pid);
3035            buf.append(" uid=");
3036            buf.append(uid);
3037            buf.append(" gids={");
3038            if (gids != null) {
3039                for (int gi=0; gi<gids.length; gi++) {
3040                    if (gi != 0) buf.append(", ");
3041                    buf.append(gids[gi]);
3042
3043                }
3044            }
3045            buf.append("}");
3046            if (requiredAbi != null) {
3047                buf.append(" abi=");
3048                buf.append(requiredAbi);
3049            }
3050            Slog.i(TAG, buf.toString());
3051            app.setPid(startResult.pid);
3052            app.usingWrapper = startResult.usingWrapper;
3053            app.removed = false;
3054            synchronized (mPidsSelfLocked) {
3055                this.mPidsSelfLocked.put(startResult.pid, app);
3056                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3057                msg.obj = app;
3058                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3059                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3060            }
3061            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
3062                    app.processName, app.info.uid);
3063            if (app.isolated) {
3064                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3065            }
3066        } catch (RuntimeException e) {
3067            // XXX do better error recovery.
3068            app.setPid(0);
3069            Slog.e(TAG, "Failure starting process " + app.processName, e);
3070        }
3071    }
3072
3073    void updateUsageStats(ActivityRecord component, boolean resumed) {
3074        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3075        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3076        if (resumed) {
3077            mUsageStatsService.noteResumeComponent(component.realActivity);
3078            synchronized (stats) {
3079                stats.noteActivityResumedLocked(component.app.uid);
3080            }
3081        } else {
3082            mUsageStatsService.notePauseComponent(component.realActivity);
3083            synchronized (stats) {
3084                stats.noteActivityPausedLocked(component.app.uid);
3085            }
3086        }
3087    }
3088
3089    Intent getHomeIntent() {
3090        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3091        intent.setComponent(mTopComponent);
3092        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3093            intent.addCategory(Intent.CATEGORY_HOME);
3094        }
3095        return intent;
3096    }
3097
3098    boolean startHomeActivityLocked(int userId) {
3099        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3100                && mTopAction == null) {
3101            // We are running in factory test mode, but unable to find
3102            // the factory test app, so just sit around displaying the
3103            // error message and don't try to start anything.
3104            return false;
3105        }
3106        Intent intent = getHomeIntent();
3107        ActivityInfo aInfo =
3108            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3109        if (aInfo != null) {
3110            intent.setComponent(new ComponentName(
3111                    aInfo.applicationInfo.packageName, aInfo.name));
3112            // Don't do this if the home app is currently being
3113            // instrumented.
3114            aInfo = new ActivityInfo(aInfo);
3115            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3116            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3117                    aInfo.applicationInfo.uid, true);
3118            if (app == null || app.instrumentationClass == null) {
3119                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3120                mStackSupervisor.startHomeActivity(intent, aInfo);
3121            }
3122        }
3123
3124        return true;
3125    }
3126
3127    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3128        ActivityInfo ai = null;
3129        ComponentName comp = intent.getComponent();
3130        try {
3131            if (comp != null) {
3132                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3133            } else {
3134                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3135                        intent,
3136                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3137                            flags, userId);
3138
3139                if (info != null) {
3140                    ai = info.activityInfo;
3141                }
3142            }
3143        } catch (RemoteException e) {
3144            // ignore
3145        }
3146
3147        return ai;
3148    }
3149
3150    /**
3151     * Starts the "new version setup screen" if appropriate.
3152     */
3153    void startSetupActivityLocked() {
3154        // Only do this once per boot.
3155        if (mCheckedForSetup) {
3156            return;
3157        }
3158
3159        // We will show this screen if the current one is a different
3160        // version than the last one shown, and we are not running in
3161        // low-level factory test mode.
3162        final ContentResolver resolver = mContext.getContentResolver();
3163        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3164                Settings.Global.getInt(resolver,
3165                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3166            mCheckedForSetup = true;
3167
3168            // See if we should be showing the platform update setup UI.
3169            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3170            List<ResolveInfo> ris = mContext.getPackageManager()
3171                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3172
3173            // We don't allow third party apps to replace this.
3174            ResolveInfo ri = null;
3175            for (int i=0; ris != null && i<ris.size(); i++) {
3176                if ((ris.get(i).activityInfo.applicationInfo.flags
3177                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3178                    ri = ris.get(i);
3179                    break;
3180                }
3181            }
3182
3183            if (ri != null) {
3184                String vers = ri.activityInfo.metaData != null
3185                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3186                        : null;
3187                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3188                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3189                            Intent.METADATA_SETUP_VERSION);
3190                }
3191                String lastVers = Settings.Secure.getString(
3192                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3193                if (vers != null && !vers.equals(lastVers)) {
3194                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3195                    intent.setComponent(new ComponentName(
3196                            ri.activityInfo.packageName, ri.activityInfo.name));
3197                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3198                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3199                }
3200            }
3201        }
3202    }
3203
3204    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3205        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3206    }
3207
3208    void enforceNotIsolatedCaller(String caller) {
3209        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3210            throw new SecurityException("Isolated process not allowed to call " + caller);
3211        }
3212    }
3213
3214    @Override
3215    public int getFrontActivityScreenCompatMode() {
3216        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3217        synchronized (this) {
3218            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3219        }
3220    }
3221
3222    @Override
3223    public void setFrontActivityScreenCompatMode(int mode) {
3224        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3225                "setFrontActivityScreenCompatMode");
3226        synchronized (this) {
3227            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3228        }
3229    }
3230
3231    @Override
3232    public int getPackageScreenCompatMode(String packageName) {
3233        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3234        synchronized (this) {
3235            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3236        }
3237    }
3238
3239    @Override
3240    public void setPackageScreenCompatMode(String packageName, int mode) {
3241        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3242                "setPackageScreenCompatMode");
3243        synchronized (this) {
3244            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3245        }
3246    }
3247
3248    @Override
3249    public boolean getPackageAskScreenCompat(String packageName) {
3250        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3251        synchronized (this) {
3252            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3253        }
3254    }
3255
3256    @Override
3257    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3258        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3259                "setPackageAskScreenCompat");
3260        synchronized (this) {
3261            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3262        }
3263    }
3264
3265    private void dispatchProcessesChanged() {
3266        int N;
3267        synchronized (this) {
3268            N = mPendingProcessChanges.size();
3269            if (mActiveProcessChanges.length < N) {
3270                mActiveProcessChanges = new ProcessChangeItem[N];
3271            }
3272            mPendingProcessChanges.toArray(mActiveProcessChanges);
3273            mAvailProcessChanges.addAll(mPendingProcessChanges);
3274            mPendingProcessChanges.clear();
3275            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3276        }
3277
3278        int i = mProcessObservers.beginBroadcast();
3279        while (i > 0) {
3280            i--;
3281            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3282            if (observer != null) {
3283                try {
3284                    for (int j=0; j<N; j++) {
3285                        ProcessChangeItem item = mActiveProcessChanges[j];
3286                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3287                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3288                                    + item.pid + " uid=" + item.uid + ": "
3289                                    + item.foregroundActivities);
3290                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3291                                    item.foregroundActivities);
3292                        }
3293                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3294                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3295                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3296                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3297                        }
3298                    }
3299                } catch (RemoteException e) {
3300                }
3301            }
3302        }
3303        mProcessObservers.finishBroadcast();
3304    }
3305
3306    private void dispatchProcessDied(int pid, int uid) {
3307        int i = mProcessObservers.beginBroadcast();
3308        while (i > 0) {
3309            i--;
3310            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3311            if (observer != null) {
3312                try {
3313                    observer.onProcessDied(pid, uid);
3314                } catch (RemoteException e) {
3315                }
3316            }
3317        }
3318        mProcessObservers.finishBroadcast();
3319    }
3320
3321    final void doPendingActivityLaunchesLocked(boolean doResume) {
3322        final int N = mPendingActivityLaunches.size();
3323        if (N <= 0) {
3324            return;
3325        }
3326        for (int i=0; i<N; i++) {
3327            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3328            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
3329                    doResume && i == (N-1), null);
3330        }
3331        mPendingActivityLaunches.clear();
3332    }
3333
3334    @Override
3335    public final int startActivity(IApplicationThread caller, String callingPackage,
3336            Intent intent, String resolvedType, IBinder resultTo,
3337            String resultWho, int requestCode, int startFlags,
3338            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3339        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3340                resultWho, requestCode,
3341                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3342    }
3343
3344    @Override
3345    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3346            Intent intent, String resolvedType, IBinder resultTo,
3347            String resultWho, int requestCode, int startFlags,
3348            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3349        enforceNotIsolatedCaller("startActivity");
3350        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3351                false, true, "startActivity", null);
3352        // TODO: Switch to user app stacks here.
3353        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3354                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3355                null, null, options, userId, null);
3356    }
3357
3358    @Override
3359    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3360            Intent intent, String resolvedType, IBinder resultTo,
3361            String resultWho, int requestCode, int startFlags, String profileFile,
3362            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3363        enforceNotIsolatedCaller("startActivityAndWait");
3364        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3365                false, true, "startActivityAndWait", null);
3366        WaitResult res = new WaitResult();
3367        // TODO: Switch to user app stacks here.
3368        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3369                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3370                res, null, options, UserHandle.getCallingUserId(), null);
3371        return res;
3372    }
3373
3374    @Override
3375    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3376            Intent intent, String resolvedType, IBinder resultTo,
3377            String resultWho, int requestCode, int startFlags, Configuration config,
3378            Bundle options, int userId) {
3379        enforceNotIsolatedCaller("startActivityWithConfig");
3380        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3381                false, true, "startActivityWithConfig", null);
3382        // TODO: Switch to user app stacks here.
3383        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3384                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3385                null, null, null, config, options, userId, null);
3386        return ret;
3387    }
3388
3389    @Override
3390    public int startActivityIntentSender(IApplicationThread caller,
3391            IntentSender intent, Intent fillInIntent, String resolvedType,
3392            IBinder resultTo, String resultWho, int requestCode,
3393            int flagsMask, int flagsValues, Bundle options) {
3394        enforceNotIsolatedCaller("startActivityIntentSender");
3395        // Refuse possible leaked file descriptors
3396        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3397            throw new IllegalArgumentException("File descriptors passed in Intent");
3398        }
3399
3400        IIntentSender sender = intent.getTarget();
3401        if (!(sender instanceof PendingIntentRecord)) {
3402            throw new IllegalArgumentException("Bad PendingIntent object");
3403        }
3404
3405        PendingIntentRecord pir = (PendingIntentRecord)sender;
3406
3407        synchronized (this) {
3408            // If this is coming from the currently resumed activity, it is
3409            // effectively saying that app switches are allowed at this point.
3410            final ActivityStack stack = getFocusedStack();
3411            if (stack.mResumedActivity != null &&
3412                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3413                mAppSwitchesAllowedTime = 0;
3414            }
3415        }
3416        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3417                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3418        return ret;
3419    }
3420
3421    @Override
3422    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3423            Intent intent, String resolvedType, IVoiceInteractionSession session,
3424            IVoiceInteractor interactor, int startFlags, String profileFile,
3425            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3426        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3427                != PackageManager.PERMISSION_GRANTED) {
3428            String msg = "Permission Denial: startVoiceActivity() from pid="
3429                    + Binder.getCallingPid()
3430                    + ", uid=" + Binder.getCallingUid()
3431                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3432            Slog.w(TAG, msg);
3433            throw new SecurityException(msg);
3434        }
3435        if (session == null || interactor == null) {
3436            throw new NullPointerException("null session or interactor");
3437        }
3438        userId = handleIncomingUser(callingPid, callingUid, userId,
3439                false, true, "startVoiceActivity", null);
3440        // TODO: Switch to user app stacks here.
3441        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3442                resolvedType, session, interactor, null, null, 0, startFlags,
3443                profileFile, profileFd, null, null, options, userId, null);
3444    }
3445
3446    @Override
3447    public boolean startNextMatchingActivity(IBinder callingActivity,
3448            Intent intent, Bundle options) {
3449        // Refuse possible leaked file descriptors
3450        if (intent != null && intent.hasFileDescriptors() == true) {
3451            throw new IllegalArgumentException("File descriptors passed in Intent");
3452        }
3453
3454        synchronized (this) {
3455            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3456            if (r == null) {
3457                ActivityOptions.abort(options);
3458                return false;
3459            }
3460            if (r.app == null || r.app.thread == null) {
3461                // The caller is not running...  d'oh!
3462                ActivityOptions.abort(options);
3463                return false;
3464            }
3465            intent = new Intent(intent);
3466            // The caller is not allowed to change the data.
3467            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3468            // And we are resetting to find the next component...
3469            intent.setComponent(null);
3470
3471            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3472
3473            ActivityInfo aInfo = null;
3474            try {
3475                List<ResolveInfo> resolves =
3476                    AppGlobals.getPackageManager().queryIntentActivities(
3477                            intent, r.resolvedType,
3478                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3479                            UserHandle.getCallingUserId());
3480
3481                // Look for the original activity in the list...
3482                final int N = resolves != null ? resolves.size() : 0;
3483                for (int i=0; i<N; i++) {
3484                    ResolveInfo rInfo = resolves.get(i);
3485                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3486                            && rInfo.activityInfo.name.equals(r.info.name)) {
3487                        // We found the current one...  the next matching is
3488                        // after it.
3489                        i++;
3490                        if (i<N) {
3491                            aInfo = resolves.get(i).activityInfo;
3492                        }
3493                        if (debug) {
3494                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3495                                    + "/" + r.info.name);
3496                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3497                                    + "/" + aInfo.name);
3498                        }
3499                        break;
3500                    }
3501                }
3502            } catch (RemoteException e) {
3503            }
3504
3505            if (aInfo == null) {
3506                // Nobody who is next!
3507                ActivityOptions.abort(options);
3508                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3509                return false;
3510            }
3511
3512            intent.setComponent(new ComponentName(
3513                    aInfo.applicationInfo.packageName, aInfo.name));
3514            intent.setFlags(intent.getFlags()&~(
3515                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3516                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3517                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3518                    Intent.FLAG_ACTIVITY_NEW_TASK));
3519
3520            // Okay now we need to start the new activity, replacing the
3521            // currently running activity.  This is a little tricky because
3522            // we want to start the new one as if the current one is finished,
3523            // but not finish the current one first so that there is no flicker.
3524            // And thus...
3525            final boolean wasFinishing = r.finishing;
3526            r.finishing = true;
3527
3528            // Propagate reply information over to the new activity.
3529            final ActivityRecord resultTo = r.resultTo;
3530            final String resultWho = r.resultWho;
3531            final int requestCode = r.requestCode;
3532            r.resultTo = null;
3533            if (resultTo != null) {
3534                resultTo.removeResultsLocked(r, resultWho, requestCode);
3535            }
3536
3537            final long origId = Binder.clearCallingIdentity();
3538            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3539                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3540                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3541                    options, false, null, null);
3542            Binder.restoreCallingIdentity(origId);
3543
3544            r.finishing = wasFinishing;
3545            if (res != ActivityManager.START_SUCCESS) {
3546                return false;
3547            }
3548            return true;
3549        }
3550    }
3551
3552    final int startActivityInPackage(int uid, String callingPackage,
3553            Intent intent, String resolvedType, IBinder resultTo,
3554            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3555                    IActivityContainer container) {
3556
3557        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3558                false, true, "startActivityInPackage", null);
3559
3560        // TODO: Switch to user app stacks here.
3561        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3562                null, null, resultTo, resultWho, requestCode, startFlags,
3563                null, null, null, null, options, userId, container);
3564        return ret;
3565    }
3566
3567    @Override
3568    public final int startActivities(IApplicationThread caller, String callingPackage,
3569            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3570            int userId) {
3571        enforceNotIsolatedCaller("startActivities");
3572        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3573                false, true, "startActivity", null);
3574        // TODO: Switch to user app stacks here.
3575        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3576                resolvedTypes, resultTo, options, userId);
3577        return ret;
3578    }
3579
3580    final int startActivitiesInPackage(int uid, String callingPackage,
3581            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3582            Bundle options, int userId) {
3583
3584        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3585                false, true, "startActivityInPackage", null);
3586        // TODO: Switch to user app stacks here.
3587        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3588                resultTo, options, userId);
3589        return ret;
3590    }
3591
3592    final void addRecentTaskLocked(TaskRecord task) {
3593        int N = mRecentTasks.size();
3594        // Quick case: check if the top-most recent task is the same.
3595        if (N > 0 && mRecentTasks.get(0) == task) {
3596            return;
3597        }
3598        // Another quick case: never add voice sessions.
3599        if (task.voiceSession != null) {
3600            return;
3601        }
3602        // Remove any existing entries that are the same kind of task.
3603        final Intent intent = task.intent;
3604        final boolean document = intent != null && intent.isDocument();
3605        final ComponentName comp = intent.getComponent();
3606
3607        int maxRecents = task.maxRecents - 1;
3608        for (int i=0; i<N; i++) {
3609            TaskRecord tr = mRecentTasks.get(i);
3610            if (task != tr) {
3611                if (task.userId != tr.userId) {
3612                    continue;
3613                }
3614                final Intent trIntent = tr.intent;
3615                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3616                    (intent == null || !intent.filterEquals(trIntent))) {
3617                    continue;
3618                }
3619                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3620                if (document && trIsDocument) {
3621                    // These are the same document activity (not necessarily the same doc).
3622                    if (maxRecents > 0) {
3623                        --maxRecents;
3624                        continue;
3625                    }
3626                    // Hit the maximum number of documents for this task. Fall through
3627                    // and remove this document from recents.
3628                } else if (document || trIsDocument) {
3629                    // Only one of these is a document. Not the droid we're looking for.
3630                    continue;
3631                }
3632            }
3633
3634            // Either task and tr are the same or, their affinities match or their intents match
3635            // and neither of them is a document, or they are documents using the same activity
3636            // and their maxRecents has been reached.
3637            tr.disposeThumbnail();
3638            mRecentTasks.remove(i);
3639            i--;
3640            N--;
3641            if (task.intent == null) {
3642                // If the new recent task we are adding is not fully
3643                // specified, then replace it with the existing recent task.
3644                task = tr;
3645            }
3646            mTaskPersister.notify(tr, false);
3647        }
3648        if (N >= MAX_RECENT_TASKS) {
3649            mRecentTasks.remove(N-1).disposeThumbnail();
3650        }
3651        mRecentTasks.add(0, task);
3652    }
3653
3654    @Override
3655    public void reportActivityFullyDrawn(IBinder token) {
3656        synchronized (this) {
3657            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3658            if (r == null) {
3659                return;
3660            }
3661            r.reportFullyDrawnLocked();
3662        }
3663    }
3664
3665    @Override
3666    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3667        synchronized (this) {
3668            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3669            if (r == null) {
3670                return;
3671            }
3672            final long origId = Binder.clearCallingIdentity();
3673            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3674            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3675                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3676            if (config != null) {
3677                r.frozenBeforeDestroy = true;
3678                if (!updateConfigurationLocked(config, r, false, false)) {
3679                    mStackSupervisor.resumeTopActivitiesLocked();
3680                }
3681            }
3682            Binder.restoreCallingIdentity(origId);
3683        }
3684    }
3685
3686    @Override
3687    public int getRequestedOrientation(IBinder token) {
3688        synchronized (this) {
3689            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3690            if (r == null) {
3691                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3692            }
3693            return mWindowManager.getAppOrientation(r.appToken);
3694        }
3695    }
3696
3697    /**
3698     * This is the internal entry point for handling Activity.finish().
3699     *
3700     * @param token The Binder token referencing the Activity we want to finish.
3701     * @param resultCode Result code, if any, from this Activity.
3702     * @param resultData Result data (Intent), if any, from this Activity.
3703     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3704     *            the root Activity in the task.
3705     *
3706     * @return Returns true if the activity successfully finished, or false if it is still running.
3707     */
3708    @Override
3709    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3710            boolean finishTask) {
3711        // Refuse possible leaked file descriptors
3712        if (resultData != null && resultData.hasFileDescriptors() == true) {
3713            throw new IllegalArgumentException("File descriptors passed in Intent");
3714        }
3715
3716        synchronized(this) {
3717            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3718            if (r == null) {
3719                return true;
3720            }
3721            // Keep track of the root activity of the task before we finish it
3722            TaskRecord tr = r.task;
3723            ActivityRecord rootR = tr.getRootActivity();
3724            // Do not allow task to finish in Lock Task mode.
3725            if (tr == mStackSupervisor.mLockTaskModeTask) {
3726                if (rootR == r) {
3727                    return false;
3728                }
3729            }
3730            if (mController != null) {
3731                // Find the first activity that is not finishing.
3732                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3733                if (next != null) {
3734                    // ask watcher if this is allowed
3735                    boolean resumeOK = true;
3736                    try {
3737                        resumeOK = mController.activityResuming(next.packageName);
3738                    } catch (RemoteException e) {
3739                        mController = null;
3740                        Watchdog.getInstance().setActivityController(null);
3741                    }
3742
3743                    if (!resumeOK) {
3744                        return false;
3745                    }
3746                }
3747            }
3748            final long origId = Binder.clearCallingIdentity();
3749            try {
3750                boolean res;
3751                if (finishTask && r == rootR) {
3752                    // If requested, remove the task that is associated to this activity only if it
3753                    // was the root activity in the task.  The result code and data is ignored because
3754                    // we don't support returning them across task boundaries.
3755                    res = removeTaskByIdLocked(tr.taskId, 0);
3756                } else {
3757                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3758                            resultData, "app-request", true);
3759                }
3760                return res;
3761            } finally {
3762                Binder.restoreCallingIdentity(origId);
3763            }
3764        }
3765    }
3766
3767    @Override
3768    public final void finishHeavyWeightApp() {
3769        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3770                != PackageManager.PERMISSION_GRANTED) {
3771            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3772                    + Binder.getCallingPid()
3773                    + ", uid=" + Binder.getCallingUid()
3774                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3775            Slog.w(TAG, msg);
3776            throw new SecurityException(msg);
3777        }
3778
3779        synchronized(this) {
3780            if (mHeavyWeightProcess == null) {
3781                return;
3782            }
3783
3784            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3785                    mHeavyWeightProcess.activities);
3786            for (int i=0; i<activities.size(); i++) {
3787                ActivityRecord r = activities.get(i);
3788                if (!r.finishing) {
3789                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3790                            null, "finish-heavy", true);
3791                }
3792            }
3793
3794            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3795                    mHeavyWeightProcess.userId, 0));
3796            mHeavyWeightProcess = null;
3797        }
3798    }
3799
3800    @Override
3801    public void crashApplication(int uid, int initialPid, String packageName,
3802            String message) {
3803        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3804                != PackageManager.PERMISSION_GRANTED) {
3805            String msg = "Permission Denial: crashApplication() from pid="
3806                    + Binder.getCallingPid()
3807                    + ", uid=" + Binder.getCallingUid()
3808                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3809            Slog.w(TAG, msg);
3810            throw new SecurityException(msg);
3811        }
3812
3813        synchronized(this) {
3814            ProcessRecord proc = null;
3815
3816            // Figure out which process to kill.  We don't trust that initialPid
3817            // still has any relation to current pids, so must scan through the
3818            // list.
3819            synchronized (mPidsSelfLocked) {
3820                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3821                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3822                    if (p.uid != uid) {
3823                        continue;
3824                    }
3825                    if (p.pid == initialPid) {
3826                        proc = p;
3827                        break;
3828                    }
3829                    if (p.pkgList.containsKey(packageName)) {
3830                        proc = p;
3831                    }
3832                }
3833            }
3834
3835            if (proc == null) {
3836                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3837                        + " initialPid=" + initialPid
3838                        + " packageName=" + packageName);
3839                return;
3840            }
3841
3842            if (proc.thread != null) {
3843                if (proc.pid == Process.myPid()) {
3844                    Log.w(TAG, "crashApplication: trying to crash self!");
3845                    return;
3846                }
3847                long ident = Binder.clearCallingIdentity();
3848                try {
3849                    proc.thread.scheduleCrash(message);
3850                } catch (RemoteException e) {
3851                }
3852                Binder.restoreCallingIdentity(ident);
3853            }
3854        }
3855    }
3856
3857    @Override
3858    public final void finishSubActivity(IBinder token, String resultWho,
3859            int requestCode) {
3860        synchronized(this) {
3861            final long origId = Binder.clearCallingIdentity();
3862            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3863            if (r != null) {
3864                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3865            }
3866            Binder.restoreCallingIdentity(origId);
3867        }
3868    }
3869
3870    @Override
3871    public boolean finishActivityAffinity(IBinder token) {
3872        synchronized(this) {
3873            final long origId = Binder.clearCallingIdentity();
3874            try {
3875                ActivityRecord r = ActivityRecord.isInStackLocked(token);
3876
3877                ActivityRecord rootR = r.task.getRootActivity();
3878                // Do not allow task to finish in Lock Task mode.
3879                if (r.task == mStackSupervisor.mLockTaskModeTask) {
3880                    if (rootR == r) {
3881                        Binder.restoreCallingIdentity(origId);
3882                        return false;
3883                    }
3884                }
3885                boolean res = false;
3886                if (r != null) {
3887                    res = r.task.stack.finishActivityAffinityLocked(r);
3888                }
3889                return res;
3890            } finally {
3891                Binder.restoreCallingIdentity(origId);
3892            }
3893        }
3894    }
3895
3896    @Override
3897    public boolean willActivityBeVisible(IBinder token) {
3898        synchronized(this) {
3899            ActivityStack stack = ActivityRecord.getStackLocked(token);
3900            if (stack != null) {
3901                return stack.willActivityBeVisibleLocked(token);
3902            }
3903            return false;
3904        }
3905    }
3906
3907    @Override
3908    public void overridePendingTransition(IBinder token, String packageName,
3909            int enterAnim, int exitAnim) {
3910        synchronized(this) {
3911            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3912            if (self == null) {
3913                return;
3914            }
3915
3916            final long origId = Binder.clearCallingIdentity();
3917
3918            if (self.state == ActivityState.RESUMED
3919                    || self.state == ActivityState.PAUSING) {
3920                mWindowManager.overridePendingAppTransition(packageName,
3921                        enterAnim, exitAnim, null);
3922            }
3923
3924            Binder.restoreCallingIdentity(origId);
3925        }
3926    }
3927
3928    /**
3929     * Main function for removing an existing process from the activity manager
3930     * as a result of that process going away.  Clears out all connections
3931     * to the process.
3932     */
3933    private final void handleAppDiedLocked(ProcessRecord app,
3934            boolean restarting, boolean allowRestart) {
3935        int pid = app.pid;
3936        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3937        if (!restarting) {
3938            removeLruProcessLocked(app);
3939            if (pid > 0) {
3940                ProcessList.remove(pid);
3941            }
3942        }
3943
3944        if (mProfileProc == app) {
3945            clearProfilerLocked();
3946        }
3947
3948        // Remove this application's activities from active lists.
3949        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3950
3951        app.activities.clear();
3952
3953        if (app.instrumentationClass != null) {
3954            Slog.w(TAG, "Crash of app " + app.processName
3955                  + " running instrumentation " + app.instrumentationClass);
3956            Bundle info = new Bundle();
3957            info.putString("shortMsg", "Process crashed.");
3958            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3959        }
3960
3961        if (!restarting) {
3962            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3963                // If there was nothing to resume, and we are not already
3964                // restarting this process, but there is a visible activity that
3965                // is hosted by the process...  then make sure all visible
3966                // activities are running, taking care of restarting this
3967                // process.
3968                if (hasVisibleActivities) {
3969                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3970                }
3971            }
3972        }
3973    }
3974
3975    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3976        IBinder threadBinder = thread.asBinder();
3977        // Find the application record.
3978        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3979            ProcessRecord rec = mLruProcesses.get(i);
3980            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3981                return i;
3982            }
3983        }
3984        return -1;
3985    }
3986
3987    final ProcessRecord getRecordForAppLocked(
3988            IApplicationThread thread) {
3989        if (thread == null) {
3990            return null;
3991        }
3992
3993        int appIndex = getLRURecordIndexForAppLocked(thread);
3994        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3995    }
3996
3997    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3998        // If there are no longer any background processes running,
3999        // and the app that died was not running instrumentation,
4000        // then tell everyone we are now low on memory.
4001        boolean haveBg = false;
4002        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4003            ProcessRecord rec = mLruProcesses.get(i);
4004            if (rec.thread != null
4005                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4006                haveBg = true;
4007                break;
4008            }
4009        }
4010
4011        if (!haveBg) {
4012            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4013            if (doReport) {
4014                long now = SystemClock.uptimeMillis();
4015                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4016                    doReport = false;
4017                } else {
4018                    mLastMemUsageReportTime = now;
4019                }
4020            }
4021            final ArrayList<ProcessMemInfo> memInfos
4022                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4023            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4024            long now = SystemClock.uptimeMillis();
4025            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4026                ProcessRecord rec = mLruProcesses.get(i);
4027                if (rec == dyingProc || rec.thread == null) {
4028                    continue;
4029                }
4030                if (doReport) {
4031                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4032                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4033                }
4034                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4035                    // The low memory report is overriding any current
4036                    // state for a GC request.  Make sure to do
4037                    // heavy/important/visible/foreground processes first.
4038                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4039                        rec.lastRequestedGc = 0;
4040                    } else {
4041                        rec.lastRequestedGc = rec.lastLowMemory;
4042                    }
4043                    rec.reportLowMemory = true;
4044                    rec.lastLowMemory = now;
4045                    mProcessesToGc.remove(rec);
4046                    addProcessToGcListLocked(rec);
4047                }
4048            }
4049            if (doReport) {
4050                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4051                mHandler.sendMessage(msg);
4052            }
4053            scheduleAppGcsLocked();
4054        }
4055    }
4056
4057    final void appDiedLocked(ProcessRecord app, int pid,
4058            IApplicationThread thread) {
4059
4060        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4061        synchronized (stats) {
4062            stats.noteProcessDiedLocked(app.info.uid, pid);
4063        }
4064
4065        // Clean up already done if the process has been re-started.
4066        if (app.pid == pid && app.thread != null &&
4067                app.thread.asBinder() == thread.asBinder()) {
4068            boolean doLowMem = app.instrumentationClass == null;
4069            boolean doOomAdj = doLowMem;
4070            if (!app.killedByAm) {
4071                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4072                        + ") has died.");
4073                mAllowLowerMemLevel = true;
4074            } else {
4075                // Note that we always want to do oom adj to update our state with the
4076                // new number of procs.
4077                mAllowLowerMemLevel = false;
4078                doLowMem = false;
4079            }
4080            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4081            if (DEBUG_CLEANUP) Slog.v(
4082                TAG, "Dying app: " + app + ", pid: " + pid
4083                + ", thread: " + thread.asBinder());
4084            handleAppDiedLocked(app, false, true);
4085
4086            if (doOomAdj) {
4087                updateOomAdjLocked();
4088            }
4089            if (doLowMem) {
4090                doLowMemReportIfNeededLocked(app);
4091            }
4092        } else if (app.pid != pid) {
4093            // A new process has already been started.
4094            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4095                    + ") has died and restarted (pid " + app.pid + ").");
4096            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4097        } else if (DEBUG_PROCESSES) {
4098            Slog.d(TAG, "Received spurious death notification for thread "
4099                    + thread.asBinder());
4100        }
4101    }
4102
4103    /**
4104     * If a stack trace dump file is configured, dump process stack traces.
4105     * @param clearTraces causes the dump file to be erased prior to the new
4106     *    traces being written, if true; when false, the new traces will be
4107     *    appended to any existing file content.
4108     * @param firstPids of dalvik VM processes to dump stack traces for first
4109     * @param lastPids of dalvik VM processes to dump stack traces for last
4110     * @param nativeProcs optional list of native process names to dump stack crawls
4111     * @return file containing stack traces, or null if no dump file is configured
4112     */
4113    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4114            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4115        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4116        if (tracesPath == null || tracesPath.length() == 0) {
4117            return null;
4118        }
4119
4120        File tracesFile = new File(tracesPath);
4121        try {
4122            File tracesDir = tracesFile.getParentFile();
4123            if (!tracesDir.exists()) {
4124                tracesFile.mkdirs();
4125                if (!SELinux.restorecon(tracesDir)) {
4126                    return null;
4127                }
4128            }
4129            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4130
4131            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4132            tracesFile.createNewFile();
4133            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4134        } catch (IOException e) {
4135            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4136            return null;
4137        }
4138
4139        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4140        return tracesFile;
4141    }
4142
4143    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4144            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4145        // Use a FileObserver to detect when traces finish writing.
4146        // The order of traces is considered important to maintain for legibility.
4147        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4148            @Override
4149            public synchronized void onEvent(int event, String path) { notify(); }
4150        };
4151
4152        try {
4153            observer.startWatching();
4154
4155            // First collect all of the stacks of the most important pids.
4156            if (firstPids != null) {
4157                try {
4158                    int num = firstPids.size();
4159                    for (int i = 0; i < num; i++) {
4160                        synchronized (observer) {
4161                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4162                            observer.wait(200);  // Wait for write-close, give up after 200msec
4163                        }
4164                    }
4165                } catch (InterruptedException e) {
4166                    Log.wtf(TAG, e);
4167                }
4168            }
4169
4170            // Next collect the stacks of the native pids
4171            if (nativeProcs != null) {
4172                int[] pids = Process.getPidsForCommands(nativeProcs);
4173                if (pids != null) {
4174                    for (int pid : pids) {
4175                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4176                    }
4177                }
4178            }
4179
4180            // Lastly, measure CPU usage.
4181            if (processCpuTracker != null) {
4182                processCpuTracker.init();
4183                System.gc();
4184                processCpuTracker.update();
4185                try {
4186                    synchronized (processCpuTracker) {
4187                        processCpuTracker.wait(500); // measure over 1/2 second.
4188                    }
4189                } catch (InterruptedException e) {
4190                }
4191                processCpuTracker.update();
4192
4193                // We'll take the stack crawls of just the top apps using CPU.
4194                final int N = processCpuTracker.countWorkingStats();
4195                int numProcs = 0;
4196                for (int i=0; i<N && numProcs<5; i++) {
4197                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4198                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4199                        numProcs++;
4200                        try {
4201                            synchronized (observer) {
4202                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4203                                observer.wait(200);  // Wait for write-close, give up after 200msec
4204                            }
4205                        } catch (InterruptedException e) {
4206                            Log.wtf(TAG, e);
4207                        }
4208
4209                    }
4210                }
4211            }
4212        } finally {
4213            observer.stopWatching();
4214        }
4215    }
4216
4217    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4218        if (true || IS_USER_BUILD) {
4219            return;
4220        }
4221        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4222        if (tracesPath == null || tracesPath.length() == 0) {
4223            return;
4224        }
4225
4226        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4227        StrictMode.allowThreadDiskWrites();
4228        try {
4229            final File tracesFile = new File(tracesPath);
4230            final File tracesDir = tracesFile.getParentFile();
4231            final File tracesTmp = new File(tracesDir, "__tmp__");
4232            try {
4233                if (!tracesDir.exists()) {
4234                    tracesFile.mkdirs();
4235                    if (!SELinux.restorecon(tracesDir.getPath())) {
4236                        return;
4237                    }
4238                }
4239                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4240
4241                if (tracesFile.exists()) {
4242                    tracesTmp.delete();
4243                    tracesFile.renameTo(tracesTmp);
4244                }
4245                StringBuilder sb = new StringBuilder();
4246                Time tobj = new Time();
4247                tobj.set(System.currentTimeMillis());
4248                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4249                sb.append(": ");
4250                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4251                sb.append(" since ");
4252                sb.append(msg);
4253                FileOutputStream fos = new FileOutputStream(tracesFile);
4254                fos.write(sb.toString().getBytes());
4255                if (app == null) {
4256                    fos.write("\n*** No application process!".getBytes());
4257                }
4258                fos.close();
4259                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4260            } catch (IOException e) {
4261                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4262                return;
4263            }
4264
4265            if (app != null) {
4266                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4267                firstPids.add(app.pid);
4268                dumpStackTraces(tracesPath, firstPids, null, null, null);
4269            }
4270
4271            File lastTracesFile = null;
4272            File curTracesFile = null;
4273            for (int i=9; i>=0; i--) {
4274                String name = String.format(Locale.US, "slow%02d.txt", i);
4275                curTracesFile = new File(tracesDir, name);
4276                if (curTracesFile.exists()) {
4277                    if (lastTracesFile != null) {
4278                        curTracesFile.renameTo(lastTracesFile);
4279                    } else {
4280                        curTracesFile.delete();
4281                    }
4282                }
4283                lastTracesFile = curTracesFile;
4284            }
4285            tracesFile.renameTo(curTracesFile);
4286            if (tracesTmp.exists()) {
4287                tracesTmp.renameTo(tracesFile);
4288            }
4289        } finally {
4290            StrictMode.setThreadPolicy(oldPolicy);
4291        }
4292    }
4293
4294    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4295            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4296        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4297        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4298
4299        if (mController != null) {
4300            try {
4301                // 0 == continue, -1 = kill process immediately
4302                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4303                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
4304            } catch (RemoteException e) {
4305                mController = null;
4306                Watchdog.getInstance().setActivityController(null);
4307            }
4308        }
4309
4310        long anrTime = SystemClock.uptimeMillis();
4311        if (MONITOR_CPU_USAGE) {
4312            updateCpuStatsNow();
4313        }
4314
4315        synchronized (this) {
4316            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4317            if (mShuttingDown) {
4318                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4319                return;
4320            } else if (app.notResponding) {
4321                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4322                return;
4323            } else if (app.crashing) {
4324                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4325                return;
4326            }
4327
4328            // In case we come through here for the same app before completing
4329            // this one, mark as anring now so we will bail out.
4330            app.notResponding = true;
4331
4332            // Log the ANR to the event log.
4333            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4334                    app.processName, app.info.flags, annotation);
4335
4336            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4337            firstPids.add(app.pid);
4338
4339            int parentPid = app.pid;
4340            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4341            if (parentPid != app.pid) firstPids.add(parentPid);
4342
4343            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4344
4345            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4346                ProcessRecord r = mLruProcesses.get(i);
4347                if (r != null && r.thread != null) {
4348                    int pid = r.pid;
4349                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4350                        if (r.persistent) {
4351                            firstPids.add(pid);
4352                        } else {
4353                            lastPids.put(pid, Boolean.TRUE);
4354                        }
4355                    }
4356                }
4357            }
4358        }
4359
4360        // Log the ANR to the main log.
4361        StringBuilder info = new StringBuilder();
4362        info.setLength(0);
4363        info.append("ANR in ").append(app.processName);
4364        if (activity != null && activity.shortComponentName != null) {
4365            info.append(" (").append(activity.shortComponentName).append(")");
4366        }
4367        info.append("\n");
4368        info.append("PID: ").append(app.pid).append("\n");
4369        if (annotation != null) {
4370            info.append("Reason: ").append(annotation).append("\n");
4371        }
4372        if (parent != null && parent != activity) {
4373            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4374        }
4375
4376        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4377
4378        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4379                NATIVE_STACKS_OF_INTEREST);
4380
4381        String cpuInfo = null;
4382        if (MONITOR_CPU_USAGE) {
4383            updateCpuStatsNow();
4384            synchronized (mProcessCpuThread) {
4385                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4386            }
4387            info.append(processCpuTracker.printCurrentLoad());
4388            info.append(cpuInfo);
4389        }
4390
4391        info.append(processCpuTracker.printCurrentState(anrTime));
4392
4393        Slog.e(TAG, info.toString());
4394        if (tracesFile == null) {
4395            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4396            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4397        }
4398
4399        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4400                cpuInfo, tracesFile, null);
4401
4402        if (mController != null) {
4403            try {
4404                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4405                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4406                if (res != 0) {
4407                    if (res < 0 && app.pid != MY_PID) {
4408                        Process.killProcess(app.pid);
4409                    } else {
4410                        synchronized (this) {
4411                            mServices.scheduleServiceTimeoutLocked(app);
4412                        }
4413                    }
4414                    return;
4415                }
4416            } catch (RemoteException e) {
4417                mController = null;
4418                Watchdog.getInstance().setActivityController(null);
4419            }
4420        }
4421
4422        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4423        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4424                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4425
4426        synchronized (this) {
4427            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4428                killUnneededProcessLocked(app, "background ANR");
4429                return;
4430            }
4431
4432            // Set the app's notResponding state, and look up the errorReportReceiver
4433            makeAppNotRespondingLocked(app,
4434                    activity != null ? activity.shortComponentName : null,
4435                    annotation != null ? "ANR " + annotation : "ANR",
4436                    info.toString());
4437
4438            // Bring up the infamous App Not Responding dialog
4439            Message msg = Message.obtain();
4440            HashMap<String, Object> map = new HashMap<String, Object>();
4441            msg.what = SHOW_NOT_RESPONDING_MSG;
4442            msg.obj = map;
4443            msg.arg1 = aboveSystem ? 1 : 0;
4444            map.put("app", app);
4445            if (activity != null) {
4446                map.put("activity", activity);
4447            }
4448
4449            mHandler.sendMessage(msg);
4450        }
4451    }
4452
4453    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4454        if (!mLaunchWarningShown) {
4455            mLaunchWarningShown = true;
4456            mHandler.post(new Runnable() {
4457                @Override
4458                public void run() {
4459                    synchronized (ActivityManagerService.this) {
4460                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4461                        d.show();
4462                        mHandler.postDelayed(new Runnable() {
4463                            @Override
4464                            public void run() {
4465                                synchronized (ActivityManagerService.this) {
4466                                    d.dismiss();
4467                                    mLaunchWarningShown = false;
4468                                }
4469                            }
4470                        }, 4000);
4471                    }
4472                }
4473            });
4474        }
4475    }
4476
4477    @Override
4478    public boolean clearApplicationUserData(final String packageName,
4479            final IPackageDataObserver observer, int userId) {
4480        enforceNotIsolatedCaller("clearApplicationUserData");
4481        int uid = Binder.getCallingUid();
4482        int pid = Binder.getCallingPid();
4483        userId = handleIncomingUser(pid, uid,
4484                userId, false, true, "clearApplicationUserData", null);
4485        long callingId = Binder.clearCallingIdentity();
4486        try {
4487            IPackageManager pm = AppGlobals.getPackageManager();
4488            int pkgUid = -1;
4489            synchronized(this) {
4490                try {
4491                    pkgUid = pm.getPackageUid(packageName, userId);
4492                } catch (RemoteException e) {
4493                }
4494                if (pkgUid == -1) {
4495                    Slog.w(TAG, "Invalid packageName: " + packageName);
4496                    if (observer != null) {
4497                        try {
4498                            observer.onRemoveCompleted(packageName, false);
4499                        } catch (RemoteException e) {
4500                            Slog.i(TAG, "Observer no longer exists.");
4501                        }
4502                    }
4503                    return false;
4504                }
4505                if (uid == pkgUid || checkComponentPermission(
4506                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4507                        pid, uid, -1, true)
4508                        == PackageManager.PERMISSION_GRANTED) {
4509                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4510                } else {
4511                    throw new SecurityException("PID " + pid + " does not have permission "
4512                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4513                                    + " of package " + packageName);
4514                }
4515            }
4516
4517            try {
4518                // Clear application user data
4519                pm.clearApplicationUserData(packageName, observer, userId);
4520
4521                // Remove all permissions granted from/to this package
4522                removeUriPermissionsForPackageLocked(packageName, userId, true);
4523
4524                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4525                        Uri.fromParts("package", packageName, null));
4526                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4527                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4528                        null, null, 0, null, null, null, false, false, userId);
4529            } catch (RemoteException e) {
4530            }
4531        } finally {
4532            Binder.restoreCallingIdentity(callingId);
4533        }
4534        return true;
4535    }
4536
4537    @Override
4538    public void killBackgroundProcesses(final String packageName, int userId) {
4539        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4540                != PackageManager.PERMISSION_GRANTED &&
4541                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4542                        != PackageManager.PERMISSION_GRANTED) {
4543            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4544                    + Binder.getCallingPid()
4545                    + ", uid=" + Binder.getCallingUid()
4546                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4547            Slog.w(TAG, msg);
4548            throw new SecurityException(msg);
4549        }
4550
4551        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4552                userId, true, true, "killBackgroundProcesses", null);
4553        long callingId = Binder.clearCallingIdentity();
4554        try {
4555            IPackageManager pm = AppGlobals.getPackageManager();
4556            synchronized(this) {
4557                int appId = -1;
4558                try {
4559                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4560                } catch (RemoteException e) {
4561                }
4562                if (appId == -1) {
4563                    Slog.w(TAG, "Invalid packageName: " + packageName);
4564                    return;
4565                }
4566                killPackageProcessesLocked(packageName, appId, userId,
4567                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4568            }
4569        } finally {
4570            Binder.restoreCallingIdentity(callingId);
4571        }
4572    }
4573
4574    @Override
4575    public void killAllBackgroundProcesses() {
4576        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4577                != PackageManager.PERMISSION_GRANTED) {
4578            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4579                    + Binder.getCallingPid()
4580                    + ", uid=" + Binder.getCallingUid()
4581                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4582            Slog.w(TAG, msg);
4583            throw new SecurityException(msg);
4584        }
4585
4586        long callingId = Binder.clearCallingIdentity();
4587        try {
4588            synchronized(this) {
4589                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4590                final int NP = mProcessNames.getMap().size();
4591                for (int ip=0; ip<NP; ip++) {
4592                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4593                    final int NA = apps.size();
4594                    for (int ia=0; ia<NA; ia++) {
4595                        ProcessRecord app = apps.valueAt(ia);
4596                        if (app.persistent) {
4597                            // we don't kill persistent processes
4598                            continue;
4599                        }
4600                        if (app.removed) {
4601                            procs.add(app);
4602                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4603                            app.removed = true;
4604                            procs.add(app);
4605                        }
4606                    }
4607                }
4608
4609                int N = procs.size();
4610                for (int i=0; i<N; i++) {
4611                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4612                }
4613                mAllowLowerMemLevel = true;
4614                updateOomAdjLocked();
4615                doLowMemReportIfNeededLocked(null);
4616            }
4617        } finally {
4618            Binder.restoreCallingIdentity(callingId);
4619        }
4620    }
4621
4622    @Override
4623    public void forceStopPackage(final String packageName, int userId) {
4624        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4625                != PackageManager.PERMISSION_GRANTED) {
4626            String msg = "Permission Denial: forceStopPackage() from pid="
4627                    + Binder.getCallingPid()
4628                    + ", uid=" + Binder.getCallingUid()
4629                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4630            Slog.w(TAG, msg);
4631            throw new SecurityException(msg);
4632        }
4633        final int callingPid = Binder.getCallingPid();
4634        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4635                userId, true, true, "forceStopPackage", null);
4636        long callingId = Binder.clearCallingIdentity();
4637        try {
4638            IPackageManager pm = AppGlobals.getPackageManager();
4639            synchronized(this) {
4640                int[] users = userId == UserHandle.USER_ALL
4641                        ? getUsersLocked() : new int[] { userId };
4642                for (int user : users) {
4643                    int pkgUid = -1;
4644                    try {
4645                        pkgUid = pm.getPackageUid(packageName, user);
4646                    } catch (RemoteException e) {
4647                    }
4648                    if (pkgUid == -1) {
4649                        Slog.w(TAG, "Invalid packageName: " + packageName);
4650                        continue;
4651                    }
4652                    try {
4653                        pm.setPackageStoppedState(packageName, true, user);
4654                    } catch (RemoteException e) {
4655                    } catch (IllegalArgumentException e) {
4656                        Slog.w(TAG, "Failed trying to unstop package "
4657                                + packageName + ": " + e);
4658                    }
4659                    if (isUserRunningLocked(user, false)) {
4660                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4661                    }
4662                }
4663            }
4664        } finally {
4665            Binder.restoreCallingIdentity(callingId);
4666        }
4667    }
4668
4669    /*
4670     * The pkg name and app id have to be specified.
4671     */
4672    @Override
4673    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4674        if (pkg == null) {
4675            return;
4676        }
4677        // Make sure the uid is valid.
4678        if (appid < 0) {
4679            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4680            return;
4681        }
4682        int callerUid = Binder.getCallingUid();
4683        // Only the system server can kill an application
4684        if (callerUid == Process.SYSTEM_UID) {
4685            // Post an aysnc message to kill the application
4686            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4687            msg.arg1 = appid;
4688            msg.arg2 = 0;
4689            Bundle bundle = new Bundle();
4690            bundle.putString("pkg", pkg);
4691            bundle.putString("reason", reason);
4692            msg.obj = bundle;
4693            mHandler.sendMessage(msg);
4694        } else {
4695            throw new SecurityException(callerUid + " cannot kill pkg: " +
4696                    pkg);
4697        }
4698    }
4699
4700    @Override
4701    public void closeSystemDialogs(String reason) {
4702        enforceNotIsolatedCaller("closeSystemDialogs");
4703
4704        final int pid = Binder.getCallingPid();
4705        final int uid = Binder.getCallingUid();
4706        final long origId = Binder.clearCallingIdentity();
4707        try {
4708            synchronized (this) {
4709                // Only allow this from foreground processes, so that background
4710                // applications can't abuse it to prevent system UI from being shown.
4711                if (uid >= Process.FIRST_APPLICATION_UID) {
4712                    ProcessRecord proc;
4713                    synchronized (mPidsSelfLocked) {
4714                        proc = mPidsSelfLocked.get(pid);
4715                    }
4716                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4717                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4718                                + " from background process " + proc);
4719                        return;
4720                    }
4721                }
4722                closeSystemDialogsLocked(reason);
4723            }
4724        } finally {
4725            Binder.restoreCallingIdentity(origId);
4726        }
4727    }
4728
4729    void closeSystemDialogsLocked(String reason) {
4730        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4731        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4732                | Intent.FLAG_RECEIVER_FOREGROUND);
4733        if (reason != null) {
4734            intent.putExtra("reason", reason);
4735        }
4736        mWindowManager.closeSystemDialogs(reason);
4737
4738        mStackSupervisor.closeSystemDialogsLocked();
4739
4740        broadcastIntentLocked(null, null, intent, null,
4741                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4742                Process.SYSTEM_UID, UserHandle.USER_ALL);
4743    }
4744
4745    @Override
4746    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4747        enforceNotIsolatedCaller("getProcessMemoryInfo");
4748        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4749        for (int i=pids.length-1; i>=0; i--) {
4750            ProcessRecord proc;
4751            int oomAdj;
4752            synchronized (this) {
4753                synchronized (mPidsSelfLocked) {
4754                    proc = mPidsSelfLocked.get(pids[i]);
4755                    oomAdj = proc != null ? proc.setAdj : 0;
4756                }
4757            }
4758            infos[i] = new Debug.MemoryInfo();
4759            Debug.getMemoryInfo(pids[i], infos[i]);
4760            if (proc != null) {
4761                synchronized (this) {
4762                    if (proc.thread != null && proc.setAdj == oomAdj) {
4763                        // Record this for posterity if the process has been stable.
4764                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4765                                infos[i].getTotalUss(), false, proc.pkgList);
4766                    }
4767                }
4768            }
4769        }
4770        return infos;
4771    }
4772
4773    @Override
4774    public long[] getProcessPss(int[] pids) {
4775        enforceNotIsolatedCaller("getProcessPss");
4776        long[] pss = new long[pids.length];
4777        for (int i=pids.length-1; i>=0; i--) {
4778            ProcessRecord proc;
4779            int oomAdj;
4780            synchronized (this) {
4781                synchronized (mPidsSelfLocked) {
4782                    proc = mPidsSelfLocked.get(pids[i]);
4783                    oomAdj = proc != null ? proc.setAdj : 0;
4784                }
4785            }
4786            long[] tmpUss = new long[1];
4787            pss[i] = Debug.getPss(pids[i], tmpUss);
4788            if (proc != null) {
4789                synchronized (this) {
4790                    if (proc.thread != null && proc.setAdj == oomAdj) {
4791                        // Record this for posterity if the process has been stable.
4792                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4793                    }
4794                }
4795            }
4796        }
4797        return pss;
4798    }
4799
4800    @Override
4801    public void killApplicationProcess(String processName, int uid) {
4802        if (processName == null) {
4803            return;
4804        }
4805
4806        int callerUid = Binder.getCallingUid();
4807        // Only the system server can kill an application
4808        if (callerUid == Process.SYSTEM_UID) {
4809            synchronized (this) {
4810                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4811                if (app != null && app.thread != null) {
4812                    try {
4813                        app.thread.scheduleSuicide();
4814                    } catch (RemoteException e) {
4815                        // If the other end already died, then our work here is done.
4816                    }
4817                } else {
4818                    Slog.w(TAG, "Process/uid not found attempting kill of "
4819                            + processName + " / " + uid);
4820                }
4821            }
4822        } else {
4823            throw new SecurityException(callerUid + " cannot kill app process: " +
4824                    processName);
4825        }
4826    }
4827
4828    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4829        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4830                false, true, false, false, UserHandle.getUserId(uid), reason);
4831        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4832                Uri.fromParts("package", packageName, null));
4833        if (!mProcessesReady) {
4834            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4835                    | Intent.FLAG_RECEIVER_FOREGROUND);
4836        }
4837        intent.putExtra(Intent.EXTRA_UID, uid);
4838        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4839        broadcastIntentLocked(null, null, intent,
4840                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4841                false, false,
4842                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4843    }
4844
4845    private void forceStopUserLocked(int userId, String reason) {
4846        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4847        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4848        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4849                | Intent.FLAG_RECEIVER_FOREGROUND);
4850        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4851        broadcastIntentLocked(null, null, intent,
4852                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4853                false, false,
4854                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4855    }
4856
4857    private final boolean killPackageProcessesLocked(String packageName, int appId,
4858            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4859            boolean doit, boolean evenPersistent, String reason) {
4860        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4861
4862        // Remove all processes this package may have touched: all with the
4863        // same UID (except for the system or root user), and all whose name
4864        // matches the package name.
4865        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4866        final int NP = mProcessNames.getMap().size();
4867        for (int ip=0; ip<NP; ip++) {
4868            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4869            final int NA = apps.size();
4870            for (int ia=0; ia<NA; ia++) {
4871                ProcessRecord app = apps.valueAt(ia);
4872                if (app.persistent && !evenPersistent) {
4873                    // we don't kill persistent processes
4874                    continue;
4875                }
4876                if (app.removed) {
4877                    if (doit) {
4878                        procs.add(app);
4879                    }
4880                    continue;
4881                }
4882
4883                // Skip process if it doesn't meet our oom adj requirement.
4884                if (app.setAdj < minOomAdj) {
4885                    continue;
4886                }
4887
4888                // If no package is specified, we call all processes under the
4889                // give user id.
4890                if (packageName == null) {
4891                    if (app.userId != userId) {
4892                        continue;
4893                    }
4894                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4895                        continue;
4896                    }
4897                // Package has been specified, we want to hit all processes
4898                // that match it.  We need to qualify this by the processes
4899                // that are running under the specified app and user ID.
4900                } else {
4901                    if (UserHandle.getAppId(app.uid) != appId) {
4902                        continue;
4903                    }
4904                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4905                        continue;
4906                    }
4907                    if (!app.pkgList.containsKey(packageName)) {
4908                        continue;
4909                    }
4910                }
4911
4912                // Process has passed all conditions, kill it!
4913                if (!doit) {
4914                    return true;
4915                }
4916                app.removed = true;
4917                procs.add(app);
4918            }
4919        }
4920
4921        int N = procs.size();
4922        for (int i=0; i<N; i++) {
4923            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4924        }
4925        updateOomAdjLocked();
4926        return N > 0;
4927    }
4928
4929    private final boolean forceStopPackageLocked(String name, int appId,
4930            boolean callerWillRestart, boolean purgeCache, boolean doit,
4931            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4932        int i;
4933        int N;
4934
4935        if (userId == UserHandle.USER_ALL && name == null) {
4936            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4937        }
4938
4939        if (appId < 0 && name != null) {
4940            try {
4941                appId = UserHandle.getAppId(
4942                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4943            } catch (RemoteException e) {
4944            }
4945        }
4946
4947        if (doit) {
4948            if (name != null) {
4949                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4950                        + " user=" + userId + ": " + reason);
4951            } else {
4952                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4953            }
4954
4955            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4956            for (int ip=pmap.size()-1; ip>=0; ip--) {
4957                SparseArray<Long> ba = pmap.valueAt(ip);
4958                for (i=ba.size()-1; i>=0; i--) {
4959                    boolean remove = false;
4960                    final int entUid = ba.keyAt(i);
4961                    if (name != null) {
4962                        if (userId == UserHandle.USER_ALL) {
4963                            if (UserHandle.getAppId(entUid) == appId) {
4964                                remove = true;
4965                            }
4966                        } else {
4967                            if (entUid == UserHandle.getUid(userId, appId)) {
4968                                remove = true;
4969                            }
4970                        }
4971                    } else if (UserHandle.getUserId(entUid) == userId) {
4972                        remove = true;
4973                    }
4974                    if (remove) {
4975                        ba.removeAt(i);
4976                    }
4977                }
4978                if (ba.size() == 0) {
4979                    pmap.removeAt(ip);
4980                }
4981            }
4982        }
4983
4984        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4985                -100, callerWillRestart, true, doit, evenPersistent,
4986                name == null ? ("stop user " + userId) : ("stop " + name));
4987
4988        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4989            if (!doit) {
4990                return true;
4991            }
4992            didSomething = true;
4993        }
4994
4995        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4996            if (!doit) {
4997                return true;
4998            }
4999            didSomething = true;
5000        }
5001
5002        if (name == null) {
5003            // Remove all sticky broadcasts from this user.
5004            mStickyBroadcasts.remove(userId);
5005        }
5006
5007        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5008        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5009                userId, providers)) {
5010            if (!doit) {
5011                return true;
5012            }
5013            didSomething = true;
5014        }
5015        N = providers.size();
5016        for (i=0; i<N; i++) {
5017            removeDyingProviderLocked(null, providers.get(i), true);
5018        }
5019
5020        // Remove transient permissions granted from/to this package/user
5021        removeUriPermissionsForPackageLocked(name, userId, false);
5022
5023        if (name == null || uninstalling) {
5024            // Remove pending intents.  For now we only do this when force
5025            // stopping users, because we have some problems when doing this
5026            // for packages -- app widgets are not currently cleaned up for
5027            // such packages, so they can be left with bad pending intents.
5028            if (mIntentSenderRecords.size() > 0) {
5029                Iterator<WeakReference<PendingIntentRecord>> it
5030                        = mIntentSenderRecords.values().iterator();
5031                while (it.hasNext()) {
5032                    WeakReference<PendingIntentRecord> wpir = it.next();
5033                    if (wpir == null) {
5034                        it.remove();
5035                        continue;
5036                    }
5037                    PendingIntentRecord pir = wpir.get();
5038                    if (pir == null) {
5039                        it.remove();
5040                        continue;
5041                    }
5042                    if (name == null) {
5043                        // Stopping user, remove all objects for the user.
5044                        if (pir.key.userId != userId) {
5045                            // Not the same user, skip it.
5046                            continue;
5047                        }
5048                    } else {
5049                        if (UserHandle.getAppId(pir.uid) != appId) {
5050                            // Different app id, skip it.
5051                            continue;
5052                        }
5053                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5054                            // Different user, skip it.
5055                            continue;
5056                        }
5057                        if (!pir.key.packageName.equals(name)) {
5058                            // Different package, skip it.
5059                            continue;
5060                        }
5061                    }
5062                    if (!doit) {
5063                        return true;
5064                    }
5065                    didSomething = true;
5066                    it.remove();
5067                    pir.canceled = true;
5068                    if (pir.key.activity != null) {
5069                        pir.key.activity.pendingResults.remove(pir.ref);
5070                    }
5071                }
5072            }
5073        }
5074
5075        if (doit) {
5076            if (purgeCache && name != null) {
5077                AttributeCache ac = AttributeCache.instance();
5078                if (ac != null) {
5079                    ac.removePackage(name);
5080                }
5081            }
5082            if (mBooted) {
5083                mStackSupervisor.resumeTopActivitiesLocked();
5084                mStackSupervisor.scheduleIdleLocked();
5085            }
5086        }
5087
5088        return didSomething;
5089    }
5090
5091    private final boolean removeProcessLocked(ProcessRecord app,
5092            boolean callerWillRestart, boolean allowRestart, String reason) {
5093        final String name = app.processName;
5094        final int uid = app.uid;
5095        if (DEBUG_PROCESSES) Slog.d(
5096            TAG, "Force removing proc " + app.toShortString() + " (" + name
5097            + "/" + uid + ")");
5098
5099        mProcessNames.remove(name, uid);
5100        mIsolatedProcesses.remove(app.uid);
5101        if (mHeavyWeightProcess == app) {
5102            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5103                    mHeavyWeightProcess.userId, 0));
5104            mHeavyWeightProcess = null;
5105        }
5106        boolean needRestart = false;
5107        if (app.pid > 0 && app.pid != MY_PID) {
5108            int pid = app.pid;
5109            synchronized (mPidsSelfLocked) {
5110                mPidsSelfLocked.remove(pid);
5111                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5112            }
5113            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5114                    app.processName, app.info.uid);
5115            if (app.isolated) {
5116                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5117            }
5118            killUnneededProcessLocked(app, reason);
5119            handleAppDiedLocked(app, true, allowRestart);
5120            removeLruProcessLocked(app);
5121
5122            if (app.persistent && !app.isolated) {
5123                if (!callerWillRestart) {
5124                    addAppLocked(app.info, false, null /* ABI override */);
5125                } else {
5126                    needRestart = true;
5127                }
5128            }
5129        } else {
5130            mRemovedProcesses.add(app);
5131        }
5132
5133        return needRestart;
5134    }
5135
5136    private final void processStartTimedOutLocked(ProcessRecord app) {
5137        final int pid = app.pid;
5138        boolean gone = false;
5139        synchronized (mPidsSelfLocked) {
5140            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5141            if (knownApp != null && knownApp.thread == null) {
5142                mPidsSelfLocked.remove(pid);
5143                gone = true;
5144            }
5145        }
5146
5147        if (gone) {
5148            Slog.w(TAG, "Process " + app + " failed to attach");
5149            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5150                    pid, app.uid, app.processName);
5151            mProcessNames.remove(app.processName, app.uid);
5152            mIsolatedProcesses.remove(app.uid);
5153            if (mHeavyWeightProcess == app) {
5154                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5155                        mHeavyWeightProcess.userId, 0));
5156                mHeavyWeightProcess = null;
5157            }
5158            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5159                    app.processName, app.info.uid);
5160            if (app.isolated) {
5161                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5162            }
5163            // Take care of any launching providers waiting for this process.
5164            checkAppInLaunchingProvidersLocked(app, true);
5165            // Take care of any services that are waiting for the process.
5166            mServices.processStartTimedOutLocked(app);
5167            killUnneededProcessLocked(app, "start timeout");
5168            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5169                Slog.w(TAG, "Unattached app died before backup, skipping");
5170                try {
5171                    IBackupManager bm = IBackupManager.Stub.asInterface(
5172                            ServiceManager.getService(Context.BACKUP_SERVICE));
5173                    bm.agentDisconnected(app.info.packageName);
5174                } catch (RemoteException e) {
5175                    // Can't happen; the backup manager is local
5176                }
5177            }
5178            if (isPendingBroadcastProcessLocked(pid)) {
5179                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5180                skipPendingBroadcastLocked(pid);
5181            }
5182        } else {
5183            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5184        }
5185    }
5186
5187    private final boolean attachApplicationLocked(IApplicationThread thread,
5188            int pid) {
5189
5190        // Find the application record that is being attached...  either via
5191        // the pid if we are running in multiple processes, or just pull the
5192        // next app record if we are emulating process with anonymous threads.
5193        ProcessRecord app;
5194        if (pid != MY_PID && pid >= 0) {
5195            synchronized (mPidsSelfLocked) {
5196                app = mPidsSelfLocked.get(pid);
5197            }
5198        } else {
5199            app = null;
5200        }
5201
5202        if (app == null) {
5203            Slog.w(TAG, "No pending application record for pid " + pid
5204                    + " (IApplicationThread " + thread + "); dropping process");
5205            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5206            if (pid > 0 && pid != MY_PID) {
5207                Process.killProcessQuiet(pid);
5208            } else {
5209                try {
5210                    thread.scheduleExit();
5211                } catch (Exception e) {
5212                    // Ignore exceptions.
5213                }
5214            }
5215            return false;
5216        }
5217
5218        // If this application record is still attached to a previous
5219        // process, clean it up now.
5220        if (app.thread != null) {
5221            handleAppDiedLocked(app, true, true);
5222        }
5223
5224        // Tell the process all about itself.
5225
5226        if (localLOGV) Slog.v(
5227                TAG, "Binding process pid " + pid + " to record " + app);
5228
5229        final String processName = app.processName;
5230        try {
5231            AppDeathRecipient adr = new AppDeathRecipient(
5232                    app, pid, thread);
5233            thread.asBinder().linkToDeath(adr, 0);
5234            app.deathRecipient = adr;
5235        } catch (RemoteException e) {
5236            app.resetPackageList(mProcessStats);
5237            startProcessLocked(app, "link fail", processName, null /* ABI override */);
5238            return false;
5239        }
5240
5241        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5242
5243        app.makeActive(thread, mProcessStats);
5244        app.curAdj = app.setAdj = -100;
5245        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5246        app.forcingToForeground = null;
5247        updateProcessForegroundLocked(app, false, false);
5248        app.hasShownUi = false;
5249        app.debugging = false;
5250        app.cached = false;
5251
5252        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5253
5254        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5255        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5256
5257        if (!normalMode) {
5258            Slog.i(TAG, "Launching preboot mode app: " + app);
5259        }
5260
5261        if (localLOGV) Slog.v(
5262            TAG, "New app record " + app
5263            + " thread=" + thread.asBinder() + " pid=" + pid);
5264        try {
5265            int testMode = IApplicationThread.DEBUG_OFF;
5266            if (mDebugApp != null && mDebugApp.equals(processName)) {
5267                testMode = mWaitForDebugger
5268                    ? IApplicationThread.DEBUG_WAIT
5269                    : IApplicationThread.DEBUG_ON;
5270                app.debugging = true;
5271                if (mDebugTransient) {
5272                    mDebugApp = mOrigDebugApp;
5273                    mWaitForDebugger = mOrigWaitForDebugger;
5274                }
5275            }
5276            String profileFile = app.instrumentationProfileFile;
5277            ParcelFileDescriptor profileFd = null;
5278            boolean profileAutoStop = false;
5279            if (mProfileApp != null && mProfileApp.equals(processName)) {
5280                mProfileProc = app;
5281                profileFile = mProfileFile;
5282                profileFd = mProfileFd;
5283                profileAutoStop = mAutoStopProfiler;
5284            }
5285            boolean enableOpenGlTrace = false;
5286            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5287                enableOpenGlTrace = true;
5288                mOpenGlTraceApp = null;
5289            }
5290
5291            // If the app is being launched for restore or full backup, set it up specially
5292            boolean isRestrictedBackupMode = false;
5293            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5294                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5295                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5296                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5297            }
5298
5299            ensurePackageDexOpt(app.instrumentationInfo != null
5300                    ? app.instrumentationInfo.packageName
5301                    : app.info.packageName);
5302            if (app.instrumentationClass != null) {
5303                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5304            }
5305            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5306                    + processName + " with config " + mConfiguration);
5307            ApplicationInfo appInfo = app.instrumentationInfo != null
5308                    ? app.instrumentationInfo : app.info;
5309            app.compat = compatibilityInfoForPackageLocked(appInfo);
5310            if (profileFd != null) {
5311                profileFd = profileFd.dup();
5312            }
5313            thread.bindApplication(processName, appInfo, providers,
5314                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5315                    app.instrumentationArguments, app.instrumentationWatcher,
5316                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5317                    isRestrictedBackupMode || !normalMode, app.persistent,
5318                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5319                    mCoreSettingsObserver.getCoreSettingsLocked());
5320            updateLruProcessLocked(app, false, null);
5321            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5322        } catch (Exception e) {
5323            // todo: Yikes!  What should we do?  For now we will try to
5324            // start another process, but that could easily get us in
5325            // an infinite loop of restarting processes...
5326            Slog.w(TAG, "Exception thrown during bind!", e);
5327
5328            app.resetPackageList(mProcessStats);
5329            app.unlinkDeathRecipient();
5330            startProcessLocked(app, "bind fail", processName, null /* ABI override */);
5331            return false;
5332        }
5333
5334        // Remove this record from the list of starting applications.
5335        mPersistentStartingProcesses.remove(app);
5336        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5337                "Attach application locked removing on hold: " + app);
5338        mProcessesOnHold.remove(app);
5339
5340        boolean badApp = false;
5341        boolean didSomething = false;
5342
5343        // See if the top visible activity is waiting to run in this process...
5344        if (normalMode) {
5345            try {
5346                if (mStackSupervisor.attachApplicationLocked(app)) {
5347                    didSomething = true;
5348                }
5349            } catch (Exception e) {
5350                badApp = true;
5351            }
5352        }
5353
5354        // Find any services that should be running in this process...
5355        if (!badApp) {
5356            try {
5357                didSomething |= mServices.attachApplicationLocked(app, processName);
5358            } catch (Exception e) {
5359                badApp = true;
5360            }
5361        }
5362
5363        // Check if a next-broadcast receiver is in this process...
5364        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5365            try {
5366                didSomething |= sendPendingBroadcastsLocked(app);
5367            } catch (Exception e) {
5368                // If the app died trying to launch the receiver we declare it 'bad'
5369                badApp = true;
5370            }
5371        }
5372
5373        // Check whether the next backup agent is in this process...
5374        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5375            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5376            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5377            try {
5378                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5379                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5380                        mBackupTarget.backupMode);
5381            } catch (Exception e) {
5382                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5383                e.printStackTrace();
5384            }
5385        }
5386
5387        if (badApp) {
5388            // todo: Also need to kill application to deal with all
5389            // kinds of exceptions.
5390            handleAppDiedLocked(app, false, true);
5391            return false;
5392        }
5393
5394        if (!didSomething) {
5395            updateOomAdjLocked();
5396        }
5397
5398        return true;
5399    }
5400
5401    @Override
5402    public final void attachApplication(IApplicationThread thread) {
5403        synchronized (this) {
5404            int callingPid = Binder.getCallingPid();
5405            final long origId = Binder.clearCallingIdentity();
5406            attachApplicationLocked(thread, callingPid);
5407            Binder.restoreCallingIdentity(origId);
5408        }
5409    }
5410
5411    @Override
5412    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5413        final long origId = Binder.clearCallingIdentity();
5414        synchronized (this) {
5415            ActivityStack stack = ActivityRecord.getStackLocked(token);
5416            if (stack != null) {
5417                ActivityRecord r =
5418                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5419                if (stopProfiling) {
5420                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5421                        try {
5422                            mProfileFd.close();
5423                        } catch (IOException e) {
5424                        }
5425                        clearProfilerLocked();
5426                    }
5427                }
5428            }
5429        }
5430        Binder.restoreCallingIdentity(origId);
5431    }
5432
5433    void enableScreenAfterBoot() {
5434        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5435                SystemClock.uptimeMillis());
5436        mWindowManager.enableScreenAfterBoot();
5437
5438        synchronized (this) {
5439            updateEventDispatchingLocked();
5440        }
5441    }
5442
5443    @Override
5444    public void showBootMessage(final CharSequence msg, final boolean always) {
5445        enforceNotIsolatedCaller("showBootMessage");
5446        mWindowManager.showBootMessage(msg, always);
5447    }
5448
5449    @Override
5450    public void dismissKeyguardOnNextActivity() {
5451        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5452        final long token = Binder.clearCallingIdentity();
5453        try {
5454            synchronized (this) {
5455                if (DEBUG_LOCKSCREEN) logLockScreen("");
5456                if (mLockScreenShown) {
5457                    mLockScreenShown = false;
5458                    comeOutOfSleepIfNeededLocked();
5459                }
5460                mStackSupervisor.setDismissKeyguard(true);
5461            }
5462        } finally {
5463            Binder.restoreCallingIdentity(token);
5464        }
5465    }
5466
5467    final void finishBooting() {
5468        // Register receivers to handle package update events
5469        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5470
5471        synchronized (this) {
5472            // Ensure that any processes we had put on hold are now started
5473            // up.
5474            final int NP = mProcessesOnHold.size();
5475            if (NP > 0) {
5476                ArrayList<ProcessRecord> procs =
5477                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5478                for (int ip=0; ip<NP; ip++) {
5479                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5480                            + procs.get(ip));
5481                    startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */);
5482                }
5483            }
5484
5485            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5486                // Start looking for apps that are abusing wake locks.
5487                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5488                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5489                // Tell anyone interested that we are done booting!
5490                SystemProperties.set("sys.boot_completed", "1");
5491                SystemProperties.set("dev.bootcomplete", "1");
5492                for (int i=0; i<mStartedUsers.size(); i++) {
5493                    UserStartedState uss = mStartedUsers.valueAt(i);
5494                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5495                        uss.mState = UserStartedState.STATE_RUNNING;
5496                        final int userId = mStartedUsers.keyAt(i);
5497                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5498                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5499                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5500                        broadcastIntentLocked(null, null, intent, null,
5501                                new IIntentReceiver.Stub() {
5502                                    @Override
5503                                    public void performReceive(Intent intent, int resultCode,
5504                                            String data, Bundle extras, boolean ordered,
5505                                            boolean sticky, int sendingUser) {
5506                                        synchronized (ActivityManagerService.this) {
5507                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5508                                                    true, false);
5509                                        }
5510                                    }
5511                                },
5512                                0, null, null,
5513                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5514                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5515                                userId);
5516                    }
5517                }
5518                scheduleStartProfilesLocked();
5519            }
5520        }
5521    }
5522
5523    final void ensureBootCompleted() {
5524        boolean booting;
5525        boolean enableScreen;
5526        synchronized (this) {
5527            booting = mBooting;
5528            mBooting = false;
5529            enableScreen = !mBooted;
5530            mBooted = true;
5531        }
5532
5533        if (booting) {
5534            finishBooting();
5535        }
5536
5537        if (enableScreen) {
5538            enableScreenAfterBoot();
5539        }
5540    }
5541
5542    @Override
5543    public final void activityResumed(IBinder token) {
5544        final long origId = Binder.clearCallingIdentity();
5545        synchronized(this) {
5546            ActivityStack stack = ActivityRecord.getStackLocked(token);
5547            if (stack != null) {
5548                ActivityRecord.activityResumedLocked(token);
5549            }
5550        }
5551        Binder.restoreCallingIdentity(origId);
5552    }
5553
5554    @Override
5555    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5556        final long origId = Binder.clearCallingIdentity();
5557        synchronized(this) {
5558            ActivityStack stack = ActivityRecord.getStackLocked(token);
5559            if (stack != null) {
5560                stack.activityPausedLocked(token, false, persistentState);
5561            }
5562        }
5563        Binder.restoreCallingIdentity(origId);
5564    }
5565
5566    @Override
5567    public final void activityStopped(IBinder token, Bundle icicle,
5568            PersistableBundle persistentState, CharSequence description) {
5569        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5570
5571        // Refuse possible leaked file descriptors
5572        if (icicle != null && icicle.hasFileDescriptors()) {
5573            throw new IllegalArgumentException("File descriptors passed in Bundle");
5574        }
5575
5576        final long origId = Binder.clearCallingIdentity();
5577
5578        synchronized (this) {
5579            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5580            if (r != null) {
5581                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5582            }
5583        }
5584
5585        trimApplications();
5586
5587        Binder.restoreCallingIdentity(origId);
5588    }
5589
5590    @Override
5591    public final void activityDestroyed(IBinder token) {
5592        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5593        synchronized (this) {
5594            ActivityStack stack = ActivityRecord.getStackLocked(token);
5595            if (stack != null) {
5596                stack.activityDestroyedLocked(token);
5597            }
5598        }
5599    }
5600
5601    @Override
5602    public String getCallingPackage(IBinder token) {
5603        synchronized (this) {
5604            ActivityRecord r = getCallingRecordLocked(token);
5605            return r != null ? r.info.packageName : null;
5606        }
5607    }
5608
5609    @Override
5610    public ComponentName getCallingActivity(IBinder token) {
5611        synchronized (this) {
5612            ActivityRecord r = getCallingRecordLocked(token);
5613            return r != null ? r.intent.getComponent() : null;
5614        }
5615    }
5616
5617    private ActivityRecord getCallingRecordLocked(IBinder token) {
5618        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5619        if (r == null) {
5620            return null;
5621        }
5622        return r.resultTo;
5623    }
5624
5625    @Override
5626    public ComponentName getActivityClassForToken(IBinder token) {
5627        synchronized(this) {
5628            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5629            if (r == null) {
5630                return null;
5631            }
5632            return r.intent.getComponent();
5633        }
5634    }
5635
5636    @Override
5637    public String getPackageForToken(IBinder token) {
5638        synchronized(this) {
5639            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5640            if (r == null) {
5641                return null;
5642            }
5643            return r.packageName;
5644        }
5645    }
5646
5647    @Override
5648    public IIntentSender getIntentSender(int type,
5649            String packageName, IBinder token, String resultWho,
5650            int requestCode, Intent[] intents, String[] resolvedTypes,
5651            int flags, Bundle options, int userId) {
5652        enforceNotIsolatedCaller("getIntentSender");
5653        // Refuse possible leaked file descriptors
5654        if (intents != null) {
5655            if (intents.length < 1) {
5656                throw new IllegalArgumentException("Intents array length must be >= 1");
5657            }
5658            for (int i=0; i<intents.length; i++) {
5659                Intent intent = intents[i];
5660                if (intent != null) {
5661                    if (intent.hasFileDescriptors()) {
5662                        throw new IllegalArgumentException("File descriptors passed in Intent");
5663                    }
5664                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5665                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5666                        throw new IllegalArgumentException(
5667                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5668                    }
5669                    intents[i] = new Intent(intent);
5670                }
5671            }
5672            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5673                throw new IllegalArgumentException(
5674                        "Intent array length does not match resolvedTypes length");
5675            }
5676        }
5677        if (options != null) {
5678            if (options.hasFileDescriptors()) {
5679                throw new IllegalArgumentException("File descriptors passed in options");
5680            }
5681        }
5682
5683        synchronized(this) {
5684            int callingUid = Binder.getCallingUid();
5685            int origUserId = userId;
5686            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5687                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5688                    "getIntentSender", null);
5689            if (origUserId == UserHandle.USER_CURRENT) {
5690                // We don't want to evaluate this until the pending intent is
5691                // actually executed.  However, we do want to always do the
5692                // security checking for it above.
5693                userId = UserHandle.USER_CURRENT;
5694            }
5695            try {
5696                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5697                    int uid = AppGlobals.getPackageManager()
5698                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5699                    if (!UserHandle.isSameApp(callingUid, uid)) {
5700                        String msg = "Permission Denial: getIntentSender() from pid="
5701                            + Binder.getCallingPid()
5702                            + ", uid=" + Binder.getCallingUid()
5703                            + ", (need uid=" + uid + ")"
5704                            + " is not allowed to send as package " + packageName;
5705                        Slog.w(TAG, msg);
5706                        throw new SecurityException(msg);
5707                    }
5708                }
5709
5710                return getIntentSenderLocked(type, packageName, callingUid, userId,
5711                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5712
5713            } catch (RemoteException e) {
5714                throw new SecurityException(e);
5715            }
5716        }
5717    }
5718
5719    IIntentSender getIntentSenderLocked(int type, String packageName,
5720            int callingUid, int userId, IBinder token, String resultWho,
5721            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5722            Bundle options) {
5723        if (DEBUG_MU)
5724            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5725        ActivityRecord activity = null;
5726        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5727            activity = ActivityRecord.isInStackLocked(token);
5728            if (activity == null) {
5729                return null;
5730            }
5731            if (activity.finishing) {
5732                return null;
5733            }
5734        }
5735
5736        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5737        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5738        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5739        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5740                |PendingIntent.FLAG_UPDATE_CURRENT);
5741
5742        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5743                type, packageName, activity, resultWho,
5744                requestCode, intents, resolvedTypes, flags, options, userId);
5745        WeakReference<PendingIntentRecord> ref;
5746        ref = mIntentSenderRecords.get(key);
5747        PendingIntentRecord rec = ref != null ? ref.get() : null;
5748        if (rec != null) {
5749            if (!cancelCurrent) {
5750                if (updateCurrent) {
5751                    if (rec.key.requestIntent != null) {
5752                        rec.key.requestIntent.replaceExtras(intents != null ?
5753                                intents[intents.length - 1] : null);
5754                    }
5755                    if (intents != null) {
5756                        intents[intents.length-1] = rec.key.requestIntent;
5757                        rec.key.allIntents = intents;
5758                        rec.key.allResolvedTypes = resolvedTypes;
5759                    } else {
5760                        rec.key.allIntents = null;
5761                        rec.key.allResolvedTypes = null;
5762                    }
5763                }
5764                return rec;
5765            }
5766            rec.canceled = true;
5767            mIntentSenderRecords.remove(key);
5768        }
5769        if (noCreate) {
5770            return rec;
5771        }
5772        rec = new PendingIntentRecord(this, key, callingUid);
5773        mIntentSenderRecords.put(key, rec.ref);
5774        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5775            if (activity.pendingResults == null) {
5776                activity.pendingResults
5777                        = new HashSet<WeakReference<PendingIntentRecord>>();
5778            }
5779            activity.pendingResults.add(rec.ref);
5780        }
5781        return rec;
5782    }
5783
5784    @Override
5785    public void cancelIntentSender(IIntentSender sender) {
5786        if (!(sender instanceof PendingIntentRecord)) {
5787            return;
5788        }
5789        synchronized(this) {
5790            PendingIntentRecord rec = (PendingIntentRecord)sender;
5791            try {
5792                int uid = AppGlobals.getPackageManager()
5793                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5794                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5795                    String msg = "Permission Denial: cancelIntentSender() from pid="
5796                        + Binder.getCallingPid()
5797                        + ", uid=" + Binder.getCallingUid()
5798                        + " is not allowed to cancel packges "
5799                        + rec.key.packageName;
5800                    Slog.w(TAG, msg);
5801                    throw new SecurityException(msg);
5802                }
5803            } catch (RemoteException e) {
5804                throw new SecurityException(e);
5805            }
5806            cancelIntentSenderLocked(rec, true);
5807        }
5808    }
5809
5810    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5811        rec.canceled = true;
5812        mIntentSenderRecords.remove(rec.key);
5813        if (cleanActivity && rec.key.activity != null) {
5814            rec.key.activity.pendingResults.remove(rec.ref);
5815        }
5816    }
5817
5818    @Override
5819    public String getPackageForIntentSender(IIntentSender pendingResult) {
5820        if (!(pendingResult instanceof PendingIntentRecord)) {
5821            return null;
5822        }
5823        try {
5824            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5825            return res.key.packageName;
5826        } catch (ClassCastException e) {
5827        }
5828        return null;
5829    }
5830
5831    @Override
5832    public int getUidForIntentSender(IIntentSender sender) {
5833        if (sender instanceof PendingIntentRecord) {
5834            try {
5835                PendingIntentRecord res = (PendingIntentRecord)sender;
5836                return res.uid;
5837            } catch (ClassCastException e) {
5838            }
5839        }
5840        return -1;
5841    }
5842
5843    @Override
5844    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5845        if (!(pendingResult instanceof PendingIntentRecord)) {
5846            return false;
5847        }
5848        try {
5849            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5850            if (res.key.allIntents == null) {
5851                return false;
5852            }
5853            for (int i=0; i<res.key.allIntents.length; i++) {
5854                Intent intent = res.key.allIntents[i];
5855                if (intent.getPackage() != null && intent.getComponent() != null) {
5856                    return false;
5857                }
5858            }
5859            return true;
5860        } catch (ClassCastException e) {
5861        }
5862        return false;
5863    }
5864
5865    @Override
5866    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5867        if (!(pendingResult instanceof PendingIntentRecord)) {
5868            return false;
5869        }
5870        try {
5871            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5872            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5873                return true;
5874            }
5875            return false;
5876        } catch (ClassCastException e) {
5877        }
5878        return false;
5879    }
5880
5881    @Override
5882    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5883        if (!(pendingResult instanceof PendingIntentRecord)) {
5884            return null;
5885        }
5886        try {
5887            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5888            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5889        } catch (ClassCastException e) {
5890        }
5891        return null;
5892    }
5893
5894    @Override
5895    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5896        if (!(pendingResult instanceof PendingIntentRecord)) {
5897            return null;
5898        }
5899        try {
5900            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5901            Intent intent = res.key.requestIntent;
5902            if (intent != null) {
5903                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5904                        || res.lastTagPrefix.equals(prefix))) {
5905                    return res.lastTag;
5906                }
5907                res.lastTagPrefix = prefix;
5908                StringBuilder sb = new StringBuilder(128);
5909                if (prefix != null) {
5910                    sb.append(prefix);
5911                }
5912                if (intent.getAction() != null) {
5913                    sb.append(intent.getAction());
5914                } else if (intent.getComponent() != null) {
5915                    intent.getComponent().appendShortString(sb);
5916                } else {
5917                    sb.append("?");
5918                }
5919                return res.lastTag = sb.toString();
5920            }
5921        } catch (ClassCastException e) {
5922        }
5923        return null;
5924    }
5925
5926    @Override
5927    public void setProcessLimit(int max) {
5928        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5929                "setProcessLimit()");
5930        synchronized (this) {
5931            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5932            mProcessLimitOverride = max;
5933        }
5934        trimApplications();
5935    }
5936
5937    @Override
5938    public int getProcessLimit() {
5939        synchronized (this) {
5940            return mProcessLimitOverride;
5941        }
5942    }
5943
5944    void foregroundTokenDied(ForegroundToken token) {
5945        synchronized (ActivityManagerService.this) {
5946            synchronized (mPidsSelfLocked) {
5947                ForegroundToken cur
5948                    = mForegroundProcesses.get(token.pid);
5949                if (cur != token) {
5950                    return;
5951                }
5952                mForegroundProcesses.remove(token.pid);
5953                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5954                if (pr == null) {
5955                    return;
5956                }
5957                pr.forcingToForeground = null;
5958                updateProcessForegroundLocked(pr, false, false);
5959            }
5960            updateOomAdjLocked();
5961        }
5962    }
5963
5964    @Override
5965    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5966        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5967                "setProcessForeground()");
5968        synchronized(this) {
5969            boolean changed = false;
5970
5971            synchronized (mPidsSelfLocked) {
5972                ProcessRecord pr = mPidsSelfLocked.get(pid);
5973                if (pr == null && isForeground) {
5974                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5975                    return;
5976                }
5977                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5978                if (oldToken != null) {
5979                    oldToken.token.unlinkToDeath(oldToken, 0);
5980                    mForegroundProcesses.remove(pid);
5981                    if (pr != null) {
5982                        pr.forcingToForeground = null;
5983                    }
5984                    changed = true;
5985                }
5986                if (isForeground && token != null) {
5987                    ForegroundToken newToken = new ForegroundToken() {
5988                        @Override
5989                        public void binderDied() {
5990                            foregroundTokenDied(this);
5991                        }
5992                    };
5993                    newToken.pid = pid;
5994                    newToken.token = token;
5995                    try {
5996                        token.linkToDeath(newToken, 0);
5997                        mForegroundProcesses.put(pid, newToken);
5998                        pr.forcingToForeground = token;
5999                        changed = true;
6000                    } catch (RemoteException e) {
6001                        // If the process died while doing this, we will later
6002                        // do the cleanup with the process death link.
6003                    }
6004                }
6005            }
6006
6007            if (changed) {
6008                updateOomAdjLocked();
6009            }
6010        }
6011    }
6012
6013    // =========================================================
6014    // PERMISSIONS
6015    // =========================================================
6016
6017    static class PermissionController extends IPermissionController.Stub {
6018        ActivityManagerService mActivityManagerService;
6019        PermissionController(ActivityManagerService activityManagerService) {
6020            mActivityManagerService = activityManagerService;
6021        }
6022
6023        @Override
6024        public boolean checkPermission(String permission, int pid, int uid) {
6025            return mActivityManagerService.checkPermission(permission, pid,
6026                    uid) == PackageManager.PERMISSION_GRANTED;
6027        }
6028    }
6029
6030    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6031        @Override
6032        public int checkComponentPermission(String permission, int pid, int uid,
6033                int owningUid, boolean exported) {
6034            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6035                    owningUid, exported);
6036        }
6037
6038        @Override
6039        public Object getAMSLock() {
6040            return ActivityManagerService.this;
6041        }
6042    }
6043
6044    /**
6045     * This can be called with or without the global lock held.
6046     */
6047    int checkComponentPermission(String permission, int pid, int uid,
6048            int owningUid, boolean exported) {
6049        // We might be performing an operation on behalf of an indirect binder
6050        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6051        // client identity accordingly before proceeding.
6052        Identity tlsIdentity = sCallerIdentity.get();
6053        if (tlsIdentity != null) {
6054            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6055                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6056            uid = tlsIdentity.uid;
6057            pid = tlsIdentity.pid;
6058        }
6059
6060        if (pid == MY_PID) {
6061            return PackageManager.PERMISSION_GRANTED;
6062        }
6063
6064        return ActivityManager.checkComponentPermission(permission, uid,
6065                owningUid, exported);
6066    }
6067
6068    /**
6069     * As the only public entry point for permissions checking, this method
6070     * can enforce the semantic that requesting a check on a null global
6071     * permission is automatically denied.  (Internally a null permission
6072     * string is used when calling {@link #checkComponentPermission} in cases
6073     * when only uid-based security is needed.)
6074     *
6075     * This can be called with or without the global lock held.
6076     */
6077    @Override
6078    public int checkPermission(String permission, int pid, int uid) {
6079        if (permission == null) {
6080            return PackageManager.PERMISSION_DENIED;
6081        }
6082        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6083    }
6084
6085    /**
6086     * Binder IPC calls go through the public entry point.
6087     * This can be called with or without the global lock held.
6088     */
6089    int checkCallingPermission(String permission) {
6090        return checkPermission(permission,
6091                Binder.getCallingPid(),
6092                UserHandle.getAppId(Binder.getCallingUid()));
6093    }
6094
6095    /**
6096     * This can be called with or without the global lock held.
6097     */
6098    void enforceCallingPermission(String permission, String func) {
6099        if (checkCallingPermission(permission)
6100                == PackageManager.PERMISSION_GRANTED) {
6101            return;
6102        }
6103
6104        String msg = "Permission Denial: " + func + " from pid="
6105                + Binder.getCallingPid()
6106                + ", uid=" + Binder.getCallingUid()
6107                + " requires " + permission;
6108        Slog.w(TAG, msg);
6109        throw new SecurityException(msg);
6110    }
6111
6112    /**
6113     * Determine if UID is holding permissions required to access {@link Uri} in
6114     * the given {@link ProviderInfo}. Final permission checking is always done
6115     * in {@link ContentProvider}.
6116     */
6117    private final boolean checkHoldingPermissionsLocked(
6118            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6119        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6120                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6121        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6122            return false;
6123        }
6124        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6125    }
6126
6127    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6128            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6129        if (pi.applicationInfo.uid == uid) {
6130            return true;
6131        } else if (!pi.exported) {
6132            return false;
6133        }
6134
6135        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6136        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6137        try {
6138            // check if target holds top-level <provider> permissions
6139            if (!readMet && pi.readPermission != null && considerUidPermissions
6140                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6141                readMet = true;
6142            }
6143            if (!writeMet && pi.writePermission != null && considerUidPermissions
6144                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6145                writeMet = true;
6146            }
6147
6148            // track if unprotected read/write is allowed; any denied
6149            // <path-permission> below removes this ability
6150            boolean allowDefaultRead = pi.readPermission == null;
6151            boolean allowDefaultWrite = pi.writePermission == null;
6152
6153            // check if target holds any <path-permission> that match uri
6154            final PathPermission[] pps = pi.pathPermissions;
6155            if (pps != null) {
6156                final String path = grantUri.uri.getPath();
6157                int i = pps.length;
6158                while (i > 0 && (!readMet || !writeMet)) {
6159                    i--;
6160                    PathPermission pp = pps[i];
6161                    if (pp.match(path)) {
6162                        if (!readMet) {
6163                            final String pprperm = pp.getReadPermission();
6164                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6165                                    + pprperm + " for " + pp.getPath()
6166                                    + ": match=" + pp.match(path)
6167                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6168                            if (pprperm != null) {
6169                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6170                                        == PERMISSION_GRANTED) {
6171                                    readMet = true;
6172                                } else {
6173                                    allowDefaultRead = false;
6174                                }
6175                            }
6176                        }
6177                        if (!writeMet) {
6178                            final String ppwperm = pp.getWritePermission();
6179                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6180                                    + ppwperm + " for " + pp.getPath()
6181                                    + ": match=" + pp.match(path)
6182                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6183                            if (ppwperm != null) {
6184                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6185                                        == PERMISSION_GRANTED) {
6186                                    writeMet = true;
6187                                } else {
6188                                    allowDefaultWrite = false;
6189                                }
6190                            }
6191                        }
6192                    }
6193                }
6194            }
6195
6196            // grant unprotected <provider> read/write, if not blocked by
6197            // <path-permission> above
6198            if (allowDefaultRead) readMet = true;
6199            if (allowDefaultWrite) writeMet = true;
6200
6201        } catch (RemoteException e) {
6202            return false;
6203        }
6204
6205        return readMet && writeMet;
6206    }
6207
6208    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6209        ProviderInfo pi = null;
6210        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6211        if (cpr != null) {
6212            pi = cpr.info;
6213        } else {
6214            try {
6215                pi = AppGlobals.getPackageManager().resolveContentProvider(
6216                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6217            } catch (RemoteException ex) {
6218            }
6219        }
6220        return pi;
6221    }
6222
6223    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6224        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6225        if (targetUris != null) {
6226            return targetUris.get(grantUri);
6227        }
6228        return null;
6229    }
6230
6231    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6232            String targetPkg, int targetUid, GrantUri grantUri) {
6233        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6234        if (targetUris == null) {
6235            targetUris = Maps.newArrayMap();
6236            mGrantedUriPermissions.put(targetUid, targetUris);
6237        }
6238
6239        UriPermission perm = targetUris.get(grantUri);
6240        if (perm == null) {
6241            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6242            targetUris.put(grantUri, perm);
6243        }
6244
6245        return perm;
6246    }
6247
6248    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6249            final int modeFlags) {
6250        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6251        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6252                : UriPermission.STRENGTH_OWNED;
6253
6254        // Root gets to do everything.
6255        if (uid == 0) {
6256            return true;
6257        }
6258
6259        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6260        if (perms == null) return false;
6261
6262        // First look for exact match
6263        final UriPermission exactPerm = perms.get(grantUri);
6264        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6265            return true;
6266        }
6267
6268        // No exact match, look for prefixes
6269        final int N = perms.size();
6270        for (int i = 0; i < N; i++) {
6271            final UriPermission perm = perms.valueAt(i);
6272            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6273                    && perm.getStrength(modeFlags) >= minStrength) {
6274                return true;
6275            }
6276        }
6277
6278        return false;
6279    }
6280
6281    @Override
6282    public int checkUriPermission(Uri uri, int pid, int uid,
6283            final int modeFlags, int userId) {
6284        enforceNotIsolatedCaller("checkUriPermission");
6285
6286        // Another redirected-binder-call permissions check as in
6287        // {@link checkComponentPermission}.
6288        Identity tlsIdentity = sCallerIdentity.get();
6289        if (tlsIdentity != null) {
6290            uid = tlsIdentity.uid;
6291            pid = tlsIdentity.pid;
6292        }
6293
6294        // Our own process gets to do everything.
6295        if (pid == MY_PID) {
6296            return PackageManager.PERMISSION_GRANTED;
6297        }
6298        synchronized (this) {
6299            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6300                    ? PackageManager.PERMISSION_GRANTED
6301                    : PackageManager.PERMISSION_DENIED;
6302        }
6303    }
6304
6305    /**
6306     * Check if the targetPkg can be granted permission to access uri by
6307     * the callingUid using the given modeFlags.  Throws a security exception
6308     * if callingUid is not allowed to do this.  Returns the uid of the target
6309     * if the URI permission grant should be performed; returns -1 if it is not
6310     * needed (for example targetPkg already has permission to access the URI).
6311     * If you already know the uid of the target, you can supply it in
6312     * lastTargetUid else set that to -1.
6313     */
6314    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6315            final int modeFlags, int lastTargetUid) {
6316        if (!Intent.isAccessUriMode(modeFlags)) {
6317            return -1;
6318        }
6319
6320        if (targetPkg != null) {
6321            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6322                    "Checking grant " + targetPkg + " permission to " + grantUri);
6323        }
6324
6325        final IPackageManager pm = AppGlobals.getPackageManager();
6326
6327        // If this is not a content: uri, we can't do anything with it.
6328        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6329            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6330                    "Can't grant URI permission for non-content URI: " + grantUri);
6331            return -1;
6332        }
6333
6334        final String authority = grantUri.uri.getAuthority();
6335        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6336        if (pi == null) {
6337            Slog.w(TAG, "No content provider found for permission check: " +
6338                    grantUri.uri.toSafeString());
6339            return -1;
6340        }
6341
6342        int targetUid = lastTargetUid;
6343        if (targetUid < 0 && targetPkg != null) {
6344            try {
6345                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6346                if (targetUid < 0) {
6347                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6348                            "Can't grant URI permission no uid for: " + targetPkg);
6349                    return -1;
6350                }
6351            } catch (RemoteException ex) {
6352                return -1;
6353            }
6354        }
6355
6356        if (targetUid >= 0) {
6357            // First...  does the target actually need this permission?
6358            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6359                // No need to grant the target this permission.
6360                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6361                        "Target " + targetPkg + " already has full permission to " + grantUri);
6362                return -1;
6363            }
6364        } else {
6365            // First...  there is no target package, so can anyone access it?
6366            boolean allowed = pi.exported;
6367            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6368                if (pi.readPermission != null) {
6369                    allowed = false;
6370                }
6371            }
6372            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6373                if (pi.writePermission != null) {
6374                    allowed = false;
6375                }
6376            }
6377            if (allowed) {
6378                return -1;
6379            }
6380        }
6381
6382        /* There is a special cross user grant if:
6383         * - The target is on another user.
6384         * - Apps on the current user can access the uri without any uid permissions.
6385         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6386         * grant uri permissions.
6387         */
6388        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6389                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6390                modeFlags, false /*without considering the uid permissions*/);
6391
6392        // Second...  is the provider allowing granting of URI permissions?
6393        if (!specialCrossUserGrant) {
6394            if (!pi.grantUriPermissions) {
6395                throw new SecurityException("Provider " + pi.packageName
6396                        + "/" + pi.name
6397                        + " does not allow granting of Uri permissions (uri "
6398                        + grantUri + ")");
6399            }
6400            if (pi.uriPermissionPatterns != null) {
6401                final int N = pi.uriPermissionPatterns.length;
6402                boolean allowed = false;
6403                for (int i=0; i<N; i++) {
6404                    if (pi.uriPermissionPatterns[i] != null
6405                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6406                        allowed = true;
6407                        break;
6408                    }
6409                }
6410                if (!allowed) {
6411                    throw new SecurityException("Provider " + pi.packageName
6412                            + "/" + pi.name
6413                            + " does not allow granting of permission to path of Uri "
6414                            + grantUri);
6415                }
6416            }
6417        }
6418
6419        // Third...  does the caller itself have permission to access
6420        // this uri?
6421        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6422            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6423                // Require they hold a strong enough Uri permission
6424                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6425                    throw new SecurityException("Uid " + callingUid
6426                            + " does not have permission to uri " + grantUri);
6427                }
6428            }
6429        }
6430        return targetUid;
6431    }
6432
6433    @Override
6434    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6435            final int modeFlags, int userId) {
6436        enforceNotIsolatedCaller("checkGrantUriPermission");
6437        synchronized(this) {
6438            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6439                    new GrantUri(userId, uri, false), modeFlags, -1);
6440        }
6441    }
6442
6443    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6444            final int modeFlags, UriPermissionOwner owner) {
6445        if (!Intent.isAccessUriMode(modeFlags)) {
6446            return;
6447        }
6448
6449        // So here we are: the caller has the assumed permission
6450        // to the uri, and the target doesn't.  Let's now give this to
6451        // the target.
6452
6453        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6454                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6455
6456        final String authority = grantUri.uri.getAuthority();
6457        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6458        if (pi == null) {
6459            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6460            return;
6461        }
6462
6463        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6464            grantUri.prefix = true;
6465        }
6466        final UriPermission perm = findOrCreateUriPermissionLocked(
6467                pi.packageName, targetPkg, targetUid, grantUri);
6468        perm.grantModes(modeFlags, owner);
6469    }
6470
6471    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6472            final int modeFlags, UriPermissionOwner owner) {
6473        if (targetPkg == null) {
6474            throw new NullPointerException("targetPkg");
6475        }
6476
6477        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6478                -1);
6479        if (targetUid < 0) {
6480            return;
6481        }
6482
6483        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6484                owner);
6485    }
6486
6487    static class NeededUriGrants extends ArrayList<GrantUri> {
6488        final String targetPkg;
6489        final int targetUid;
6490        final int flags;
6491
6492        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6493            this.targetPkg = targetPkg;
6494            this.targetUid = targetUid;
6495            this.flags = flags;
6496        }
6497    }
6498
6499    /**
6500     * Like checkGrantUriPermissionLocked, but takes an Intent.
6501     */
6502    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6503            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6504        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6505                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6506                + " clip=" + (intent != null ? intent.getClipData() : null)
6507                + " from " + intent + "; flags=0x"
6508                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6509
6510        if (targetPkg == null) {
6511            throw new NullPointerException("targetPkg");
6512        }
6513
6514        if (intent == null) {
6515            return null;
6516        }
6517        Uri data = intent.getData();
6518        ClipData clip = intent.getClipData();
6519        if (data == null && clip == null) {
6520            return null;
6521        }
6522        final IPackageManager pm = AppGlobals.getPackageManager();
6523        int targetUid;
6524        if (needed != null) {
6525            targetUid = needed.targetUid;
6526        } else {
6527            try {
6528                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6529            } catch (RemoteException ex) {
6530                return null;
6531            }
6532            if (targetUid < 0) {
6533                if (DEBUG_URI_PERMISSION) {
6534                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6535                            + " on user " + targetUserId);
6536                }
6537                return null;
6538            }
6539        }
6540        if (data != null) {
6541            GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data);
6542            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6543                    targetUid);
6544            if (targetUid > 0) {
6545                if (needed == null) {
6546                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6547                }
6548                needed.add(grantUri);
6549            }
6550        }
6551        if (clip != null) {
6552            for (int i=0; i<clip.getItemCount(); i++) {
6553                Uri uri = clip.getItemAt(i).getUri();
6554                if (uri != null) {
6555                    GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri);
6556                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6557                            targetUid);
6558                    if (targetUid > 0) {
6559                        if (needed == null) {
6560                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6561                        }
6562                        needed.add(grantUri);
6563                    }
6564                } else {
6565                    Intent clipIntent = clip.getItemAt(i).getIntent();
6566                    if (clipIntent != null) {
6567                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6568                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6569                        if (newNeeded != null) {
6570                            needed = newNeeded;
6571                        }
6572                    }
6573                }
6574            }
6575        }
6576
6577        return needed;
6578    }
6579
6580    /**
6581     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6582     */
6583    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6584            UriPermissionOwner owner) {
6585        if (needed != null) {
6586            for (int i=0; i<needed.size(); i++) {
6587                GrantUri grantUri = needed.get(i);
6588                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6589                        grantUri, needed.flags, owner);
6590            }
6591        }
6592    }
6593
6594    void grantUriPermissionFromIntentLocked(int callingUid,
6595            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6596        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6597                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6598        if (needed == null) {
6599            return;
6600        }
6601
6602        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6603    }
6604
6605    @Override
6606    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6607            final int modeFlags, int userId) {
6608        enforceNotIsolatedCaller("grantUriPermission");
6609        GrantUri grantUri = new GrantUri(userId, uri, false);
6610        synchronized(this) {
6611            final ProcessRecord r = getRecordForAppLocked(caller);
6612            if (r == null) {
6613                throw new SecurityException("Unable to find app for caller "
6614                        + caller
6615                        + " when granting permission to uri " + grantUri);
6616            }
6617            if (targetPkg == null) {
6618                throw new IllegalArgumentException("null target");
6619            }
6620            if (grantUri == null) {
6621                throw new IllegalArgumentException("null uri");
6622            }
6623
6624            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6625                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6626                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6627                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6628
6629            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null);
6630        }
6631    }
6632
6633    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6634        if (perm.modeFlags == 0) {
6635            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6636                    perm.targetUid);
6637            if (perms != null) {
6638                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6639                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6640
6641                perms.remove(perm.uri);
6642                if (perms.isEmpty()) {
6643                    mGrantedUriPermissions.remove(perm.targetUid);
6644                }
6645            }
6646        }
6647    }
6648
6649    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6650        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6651
6652        final IPackageManager pm = AppGlobals.getPackageManager();
6653        final String authority = grantUri.uri.getAuthority();
6654        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6655        if (pi == null) {
6656            Slog.w(TAG, "No content provider found for permission revoke: "
6657                    + grantUri.toSafeString());
6658            return;
6659        }
6660
6661        // Does the caller have this permission on the URI?
6662        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6663            // Right now, if you are not the original owner of the permission,
6664            // you are not allowed to revoke it.
6665            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6666                throw new SecurityException("Uid " + callingUid
6667                        + " does not have permission to uri " + grantUri);
6668            //}
6669        }
6670
6671        boolean persistChanged = false;
6672
6673        // Go through all of the permissions and remove any that match.
6674        int N = mGrantedUriPermissions.size();
6675        for (int i = 0; i < N; i++) {
6676            final int targetUid = mGrantedUriPermissions.keyAt(i);
6677            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6678
6679            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6680                final UriPermission perm = it.next();
6681                if (perm.uri.sourceUserId == grantUri.sourceUserId
6682                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6683                    if (DEBUG_URI_PERMISSION)
6684                        Slog.v(TAG,
6685                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6686                    persistChanged |= perm.revokeModes(
6687                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6688                    if (perm.modeFlags == 0) {
6689                        it.remove();
6690                    }
6691                }
6692            }
6693
6694            if (perms.isEmpty()) {
6695                mGrantedUriPermissions.remove(targetUid);
6696                N--;
6697                i--;
6698            }
6699        }
6700
6701        if (persistChanged) {
6702            schedulePersistUriGrants();
6703        }
6704    }
6705
6706    @Override
6707    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6708            int userId) {
6709        enforceNotIsolatedCaller("revokeUriPermission");
6710        synchronized(this) {
6711            final ProcessRecord r = getRecordForAppLocked(caller);
6712            if (r == null) {
6713                throw new SecurityException("Unable to find app for caller "
6714                        + caller
6715                        + " when revoking permission to uri " + uri);
6716            }
6717            if (uri == null) {
6718                Slog.w(TAG, "revokeUriPermission: null uri");
6719                return;
6720            }
6721
6722            if (!Intent.isAccessUriMode(modeFlags)) {
6723                return;
6724            }
6725
6726            final IPackageManager pm = AppGlobals.getPackageManager();
6727            final String authority = uri.getAuthority();
6728            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6729            if (pi == null) {
6730                Slog.w(TAG, "No content provider found for permission revoke: "
6731                        + uri.toSafeString());
6732                return;
6733            }
6734
6735            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6736        }
6737    }
6738
6739    /**
6740     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6741     * given package.
6742     *
6743     * @param packageName Package name to match, or {@code null} to apply to all
6744     *            packages.
6745     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6746     *            to all users.
6747     * @param persistable If persistable grants should be removed.
6748     */
6749    private void removeUriPermissionsForPackageLocked(
6750            String packageName, int userHandle, boolean persistable) {
6751        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6752            throw new IllegalArgumentException("Must narrow by either package or user");
6753        }
6754
6755        boolean persistChanged = false;
6756
6757        int N = mGrantedUriPermissions.size();
6758        for (int i = 0; i < N; i++) {
6759            final int targetUid = mGrantedUriPermissions.keyAt(i);
6760            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6761
6762            // Only inspect grants matching user
6763            if (userHandle == UserHandle.USER_ALL
6764                    || userHandle == UserHandle.getUserId(targetUid)) {
6765                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6766                    final UriPermission perm = it.next();
6767
6768                    // Only inspect grants matching package
6769                    if (packageName == null || perm.sourcePkg.equals(packageName)
6770                            || perm.targetPkg.equals(packageName)) {
6771                        persistChanged |= perm.revokeModes(
6772                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6773
6774                        // Only remove when no modes remain; any persisted grants
6775                        // will keep this alive.
6776                        if (perm.modeFlags == 0) {
6777                            it.remove();
6778                        }
6779                    }
6780                }
6781
6782                if (perms.isEmpty()) {
6783                    mGrantedUriPermissions.remove(targetUid);
6784                    N--;
6785                    i--;
6786                }
6787            }
6788        }
6789
6790        if (persistChanged) {
6791            schedulePersistUriGrants();
6792        }
6793    }
6794
6795    @Override
6796    public IBinder newUriPermissionOwner(String name) {
6797        enforceNotIsolatedCaller("newUriPermissionOwner");
6798        synchronized(this) {
6799            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6800            return owner.getExternalTokenLocked();
6801        }
6802    }
6803
6804    @Override
6805    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6806            final int modeFlags, int userId) {
6807        synchronized(this) {
6808            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6809            if (owner == null) {
6810                throw new IllegalArgumentException("Unknown owner: " + token);
6811            }
6812            if (fromUid != Binder.getCallingUid()) {
6813                if (Binder.getCallingUid() != Process.myUid()) {
6814                    // Only system code can grant URI permissions on behalf
6815                    // of other users.
6816                    throw new SecurityException("nice try");
6817                }
6818            }
6819            if (targetPkg == null) {
6820                throw new IllegalArgumentException("null target");
6821            }
6822            if (uri == null) {
6823                throw new IllegalArgumentException("null uri");
6824            }
6825
6826            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false),
6827                    modeFlags, owner);
6828        }
6829    }
6830
6831    @Override
6832    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6833        synchronized(this) {
6834            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6835            if (owner == null) {
6836                throw new IllegalArgumentException("Unknown owner: " + token);
6837            }
6838
6839            if (uri == null) {
6840                owner.removeUriPermissionsLocked(mode);
6841            } else {
6842                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
6843            }
6844        }
6845    }
6846
6847    private void schedulePersistUriGrants() {
6848        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6849            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6850                    10 * DateUtils.SECOND_IN_MILLIS);
6851        }
6852    }
6853
6854    private void writeGrantedUriPermissions() {
6855        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6856
6857        // Snapshot permissions so we can persist without lock
6858        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6859        synchronized (this) {
6860            final int size = mGrantedUriPermissions.size();
6861            for (int i = 0; i < size; i++) {
6862                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6863                for (UriPermission perm : perms.values()) {
6864                    if (perm.persistedModeFlags != 0) {
6865                        persist.add(perm.snapshot());
6866                    }
6867                }
6868            }
6869        }
6870
6871        FileOutputStream fos = null;
6872        try {
6873            fos = mGrantFile.startWrite();
6874
6875            XmlSerializer out = new FastXmlSerializer();
6876            out.setOutput(fos, "utf-8");
6877            out.startDocument(null, true);
6878            out.startTag(null, TAG_URI_GRANTS);
6879            for (UriPermission.Snapshot perm : persist) {
6880                out.startTag(null, TAG_URI_GRANT);
6881                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
6882                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
6883                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6884                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6885                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6886                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6887                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6888                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6889                out.endTag(null, TAG_URI_GRANT);
6890            }
6891            out.endTag(null, TAG_URI_GRANTS);
6892            out.endDocument();
6893
6894            mGrantFile.finishWrite(fos);
6895        } catch (IOException e) {
6896            if (fos != null) {
6897                mGrantFile.failWrite(fos);
6898            }
6899        }
6900    }
6901
6902    private void readGrantedUriPermissionsLocked() {
6903        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6904
6905        final long now = System.currentTimeMillis();
6906
6907        FileInputStream fis = null;
6908        try {
6909            fis = mGrantFile.openRead();
6910            final XmlPullParser in = Xml.newPullParser();
6911            in.setInput(fis, null);
6912
6913            int type;
6914            while ((type = in.next()) != END_DOCUMENT) {
6915                final String tag = in.getName();
6916                if (type == START_TAG) {
6917                    if (TAG_URI_GRANT.equals(tag)) {
6918                        final int sourceUserId;
6919                        final int targetUserId;
6920                        final int userHandle = readIntAttribute(in,
6921                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
6922                        if (userHandle != UserHandle.USER_NULL) {
6923                            // For backwards compatibility.
6924                            sourceUserId = userHandle;
6925                            targetUserId = userHandle;
6926                        } else {
6927                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
6928                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
6929                        }
6930                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6931                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6932                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6933                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
6934                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6935                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6936
6937                        // Sanity check that provider still belongs to source package
6938                        final ProviderInfo pi = getProviderInfoLocked(
6939                                uri.getAuthority(), sourceUserId);
6940                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6941                            int targetUid = -1;
6942                            try {
6943                                targetUid = AppGlobals.getPackageManager()
6944                                        .getPackageUid(targetPkg, targetUserId);
6945                            } catch (RemoteException e) {
6946                            }
6947                            if (targetUid != -1) {
6948                                final UriPermission perm = findOrCreateUriPermissionLocked(
6949                                        sourcePkg, targetPkg, targetUid,
6950                                        new GrantUri(sourceUserId, uri, prefix));
6951                                perm.initPersistedModes(modeFlags, createdTime);
6952                            }
6953                        } else {
6954                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6955                                    + " but instead found " + pi);
6956                        }
6957                    }
6958                }
6959            }
6960        } catch (FileNotFoundException e) {
6961            // Missing grants is okay
6962        } catch (IOException e) {
6963            Log.wtf(TAG, "Failed reading Uri grants", e);
6964        } catch (XmlPullParserException e) {
6965            Log.wtf(TAG, "Failed reading Uri grants", e);
6966        } finally {
6967            IoUtils.closeQuietly(fis);
6968        }
6969    }
6970
6971    @Override
6972    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6973        enforceNotIsolatedCaller("takePersistableUriPermission");
6974
6975        Preconditions.checkFlagsArgument(modeFlags,
6976                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6977
6978        synchronized (this) {
6979            final int callingUid = Binder.getCallingUid();
6980            boolean persistChanged = false;
6981            GrantUri grantUri = new GrantUri(userId, uri, false);
6982
6983            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6984                    new GrantUri(userId, uri, false));
6985            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6986                    new GrantUri(userId, uri, true));
6987
6988            final boolean exactValid = (exactPerm != null)
6989                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
6990            final boolean prefixValid = (prefixPerm != null)
6991                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
6992
6993            if (!(exactValid || prefixValid)) {
6994                throw new SecurityException("No persistable permission grants found for UID "
6995                        + callingUid + " and Uri " + grantUri.toSafeString());
6996            }
6997
6998            if (exactValid) {
6999                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7000            }
7001            if (prefixValid) {
7002                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7003            }
7004
7005            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7006
7007            if (persistChanged) {
7008                schedulePersistUriGrants();
7009            }
7010        }
7011    }
7012
7013    @Override
7014    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7015        enforceNotIsolatedCaller("releasePersistableUriPermission");
7016
7017        Preconditions.checkFlagsArgument(modeFlags,
7018                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7019
7020        synchronized (this) {
7021            final int callingUid = Binder.getCallingUid();
7022            boolean persistChanged = false;
7023
7024            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7025                    new GrantUri(userId, uri, false));
7026            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7027                    new GrantUri(userId, uri, true));
7028            if (exactPerm == null && prefixPerm == null) {
7029                throw new SecurityException("No permission grants found for UID " + callingUid
7030                        + " and Uri " + uri.toSafeString());
7031            }
7032
7033            if (exactPerm != null) {
7034                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7035                removeUriPermissionIfNeededLocked(exactPerm);
7036            }
7037            if (prefixPerm != null) {
7038                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7039                removeUriPermissionIfNeededLocked(prefixPerm);
7040            }
7041
7042            if (persistChanged) {
7043                schedulePersistUriGrants();
7044            }
7045        }
7046    }
7047
7048    /**
7049     * Prune any older {@link UriPermission} for the given UID until outstanding
7050     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7051     *
7052     * @return if any mutations occured that require persisting.
7053     */
7054    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7055        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7056        if (perms == null) return false;
7057        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7058
7059        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7060        for (UriPermission perm : perms.values()) {
7061            if (perm.persistedModeFlags != 0) {
7062                persisted.add(perm);
7063            }
7064        }
7065
7066        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7067        if (trimCount <= 0) return false;
7068
7069        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7070        for (int i = 0; i < trimCount; i++) {
7071            final UriPermission perm = persisted.get(i);
7072
7073            if (DEBUG_URI_PERMISSION) {
7074                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7075            }
7076
7077            perm.releasePersistableModes(~0);
7078            removeUriPermissionIfNeededLocked(perm);
7079        }
7080
7081        return true;
7082    }
7083
7084    @Override
7085    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7086            String packageName, boolean incoming) {
7087        enforceNotIsolatedCaller("getPersistedUriPermissions");
7088        Preconditions.checkNotNull(packageName, "packageName");
7089
7090        final int callingUid = Binder.getCallingUid();
7091        final IPackageManager pm = AppGlobals.getPackageManager();
7092        try {
7093            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7094            if (packageUid != callingUid) {
7095                throw new SecurityException(
7096                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7097            }
7098        } catch (RemoteException e) {
7099            throw new SecurityException("Failed to verify package name ownership");
7100        }
7101
7102        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7103        synchronized (this) {
7104            if (incoming) {
7105                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7106                        callingUid);
7107                if (perms == null) {
7108                    Slog.w(TAG, "No permission grants found for " + packageName);
7109                } else {
7110                    for (UriPermission perm : perms.values()) {
7111                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7112                            result.add(perm.buildPersistedPublicApiObject());
7113                        }
7114                    }
7115                }
7116            } else {
7117                final int size = mGrantedUriPermissions.size();
7118                for (int i = 0; i < size; i++) {
7119                    final ArrayMap<GrantUri, UriPermission> perms =
7120                            mGrantedUriPermissions.valueAt(i);
7121                    for (UriPermission perm : perms.values()) {
7122                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7123                            result.add(perm.buildPersistedPublicApiObject());
7124                        }
7125                    }
7126                }
7127            }
7128        }
7129        return new ParceledListSlice<android.content.UriPermission>(result);
7130    }
7131
7132    @Override
7133    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7134        synchronized (this) {
7135            ProcessRecord app =
7136                who != null ? getRecordForAppLocked(who) : null;
7137            if (app == null) return;
7138
7139            Message msg = Message.obtain();
7140            msg.what = WAIT_FOR_DEBUGGER_MSG;
7141            msg.obj = app;
7142            msg.arg1 = waiting ? 1 : 0;
7143            mHandler.sendMessage(msg);
7144        }
7145    }
7146
7147    @Override
7148    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7149        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7150        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7151        outInfo.availMem = Process.getFreeMemory();
7152        outInfo.totalMem = Process.getTotalMemory();
7153        outInfo.threshold = homeAppMem;
7154        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7155        outInfo.hiddenAppThreshold = cachedAppMem;
7156        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7157                ProcessList.SERVICE_ADJ);
7158        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7159                ProcessList.VISIBLE_APP_ADJ);
7160        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7161                ProcessList.FOREGROUND_APP_ADJ);
7162    }
7163
7164    // =========================================================
7165    // TASK MANAGEMENT
7166    // =========================================================
7167
7168    @Override
7169    public List<IAppTask> getAppTasks() {
7170        int callingUid = Binder.getCallingUid();
7171        long ident = Binder.clearCallingIdentity();
7172        synchronized(this) {
7173            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7174            try {
7175                if (localLOGV) Slog.v(TAG, "getAppTasks");
7176
7177                final int N = mRecentTasks.size();
7178                for (int i = 0; i < N; i++) {
7179                    TaskRecord tr = mRecentTasks.get(i);
7180                    // Skip tasks that are not created by the caller
7181                    if (tr.creatorUid == callingUid) {
7182                        ActivityManager.RecentTaskInfo taskInfo =
7183                                createRecentTaskInfoFromTaskRecord(tr);
7184                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7185                        list.add(taskImpl);
7186                    }
7187                }
7188            } finally {
7189                Binder.restoreCallingIdentity(ident);
7190            }
7191            return list;
7192        }
7193    }
7194
7195    @Override
7196    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7197        final int callingUid = Binder.getCallingUid();
7198        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7199
7200        synchronized(this) {
7201            if (localLOGV) Slog.v(
7202                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7203
7204            final boolean allowed = checkCallingPermission(
7205                    android.Manifest.permission.GET_TASKS)
7206                    == PackageManager.PERMISSION_GRANTED;
7207            if (!allowed) {
7208                Slog.w(TAG, "getTasks: caller " + callingUid
7209                        + " does not hold GET_TASKS; limiting output");
7210            }
7211
7212            // TODO: Improve with MRU list from all ActivityStacks.
7213            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7214        }
7215
7216        return list;
7217    }
7218
7219    TaskRecord getMostRecentTask() {
7220        return mRecentTasks.get(0);
7221    }
7222
7223    /**
7224     * Creates a new RecentTaskInfo from a TaskRecord.
7225     */
7226    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7227        // Update the task description to reflect any changes in the task stack
7228        tr.updateTaskDescription();
7229
7230        // Compose the recent task info
7231        ActivityManager.RecentTaskInfo rti
7232                = new ActivityManager.RecentTaskInfo();
7233        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7234        rti.persistentId = tr.taskId;
7235        rti.baseIntent = new Intent(tr.getBaseIntent());
7236        rti.origActivity = tr.origActivity;
7237        rti.description = tr.lastDescription;
7238        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7239        rti.userId = tr.userId;
7240        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7241        return rti;
7242    }
7243
7244    @Override
7245    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
7246            int flags, int userId) {
7247        final int callingUid = Binder.getCallingUid();
7248        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7249                false, true, "getRecentTasks", null);
7250
7251        synchronized (this) {
7252            final boolean allowed = checkCallingPermission(
7253                    android.Manifest.permission.GET_TASKS)
7254                    == PackageManager.PERMISSION_GRANTED;
7255            if (!allowed) {
7256                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7257                        + " does not hold GET_TASKS; limiting output");
7258            }
7259            final boolean detailed = checkCallingPermission(
7260                    android.Manifest.permission.GET_DETAILED_TASKS)
7261                    == PackageManager.PERMISSION_GRANTED;
7262
7263            IPackageManager pm = AppGlobals.getPackageManager();
7264
7265            final int N = mRecentTasks.size();
7266            ArrayList<ActivityManager.RecentTaskInfo> res
7267                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7268                            maxNum < N ? maxNum : N);
7269
7270            final Set<Integer> includedUsers;
7271            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
7272                includedUsers = getProfileIdsLocked(userId);
7273            } else {
7274                includedUsers = new HashSet<Integer>();
7275            }
7276            includedUsers.add(Integer.valueOf(userId));
7277            for (int i=0; i<N && maxNum > 0; i++) {
7278                TaskRecord tr = mRecentTasks.get(i);
7279                // Only add calling user or related users recent tasks
7280                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7281
7282                // Return the entry if desired by the caller.  We always return
7283                // the first entry, because callers always expect this to be the
7284                // foreground app.  We may filter others if the caller has
7285                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7286                // we should exclude the entry.
7287
7288                if (i == 0
7289                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
7290                        || (tr.intent == null)
7291                        || ((tr.intent.getFlags()
7292                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
7293                    if (!allowed) {
7294                        // If the caller doesn't have the GET_TASKS permission, then only
7295                        // allow them to see a small subset of tasks -- their own and home.
7296                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7297                            continue;
7298                        }
7299                    }
7300                    if (tr.intent != null &&
7301                            (tr.intent.getFlags() & Intent.FLAG_ACTIVITY_AUTO_REMOVE_FROM_RECENTS)
7302                            != 0 && tr.getTopActivity() == null) {
7303                        // Don't include auto remove tasks that are finished or finishing.
7304                        continue;
7305                    }
7306
7307                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7308                    if (!detailed) {
7309                        rti.baseIntent.replaceExtras((Bundle)null);
7310                    }
7311
7312                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7313                        // Check whether this activity is currently available.
7314                        try {
7315                            if (rti.origActivity != null) {
7316                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7317                                        == null) {
7318                                    continue;
7319                                }
7320                            } else if (rti.baseIntent != null) {
7321                                if (pm.queryIntentActivities(rti.baseIntent,
7322                                        null, 0, userId) == null) {
7323                                    continue;
7324                                }
7325                            }
7326                        } catch (RemoteException e) {
7327                            // Will never happen.
7328                        }
7329                    }
7330
7331                    res.add(rti);
7332                    maxNum--;
7333                }
7334            }
7335            return res;
7336        }
7337    }
7338
7339    private TaskRecord recentTaskForIdLocked(int id) {
7340        final int N = mRecentTasks.size();
7341            for (int i=0; i<N; i++) {
7342                TaskRecord tr = mRecentTasks.get(i);
7343                if (tr.taskId == id) {
7344                    return tr;
7345                }
7346            }
7347            return null;
7348    }
7349
7350    @Override
7351    public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
7352        synchronized (this) {
7353            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7354                    "getTaskThumbnails()");
7355            TaskRecord tr = recentTaskForIdLocked(id);
7356            if (tr != null) {
7357                return tr.getTaskThumbnailsLocked();
7358            }
7359        }
7360        return null;
7361    }
7362
7363    @Override
7364    public Bitmap getTaskTopThumbnail(int id) {
7365        synchronized (this) {
7366            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7367                    "getTaskTopThumbnail()");
7368            TaskRecord tr = recentTaskForIdLocked(id);
7369            if (tr != null) {
7370                return tr.getTaskTopThumbnailLocked();
7371            }
7372        }
7373        return null;
7374    }
7375
7376    @Override
7377    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7378        synchronized (this) {
7379            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7380            if (r != null) {
7381                r.taskDescription = td;
7382                r.task.updateTaskDescription();
7383            }
7384        }
7385    }
7386
7387    @Override
7388    public boolean removeSubTask(int taskId, int subTaskIndex) {
7389        synchronized (this) {
7390            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7391                    "removeSubTask()");
7392            long ident = Binder.clearCallingIdentity();
7393            try {
7394                TaskRecord tr = recentTaskForIdLocked(taskId);
7395                if (tr != null) {
7396                    return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null;
7397                }
7398                return false;
7399            } finally {
7400                Binder.restoreCallingIdentity(ident);
7401            }
7402        }
7403    }
7404
7405    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7406        if (!pr.killedByAm) {
7407            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7408            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7409                    pr.processName, pr.setAdj, reason);
7410            pr.killedByAm = true;
7411            Process.killProcessQuiet(pr.pid);
7412        }
7413    }
7414
7415    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7416        tr.disposeThumbnail();
7417        mRecentTasks.remove(tr);
7418        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7419        Intent baseIntent = new Intent(
7420                tr.intent != null ? tr.intent : tr.affinityIntent);
7421        ComponentName component = baseIntent.getComponent();
7422        if (component == null) {
7423            Slog.w(TAG, "Now component for base intent of task: " + tr);
7424            return;
7425        }
7426
7427        // Find any running services associated with this app.
7428        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7429
7430        if (killProcesses) {
7431            // Find any running processes associated with this app.
7432            final String pkg = component.getPackageName();
7433            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7434            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7435            for (int i=0; i<pmap.size(); i++) {
7436                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7437                for (int j=0; j<uids.size(); j++) {
7438                    ProcessRecord proc = uids.valueAt(j);
7439                    if (proc.userId != tr.userId) {
7440                        continue;
7441                    }
7442                    if (!proc.pkgList.containsKey(pkg)) {
7443                        continue;
7444                    }
7445                    procs.add(proc);
7446                }
7447            }
7448
7449            // Kill the running processes.
7450            for (int i=0; i<procs.size(); i++) {
7451                ProcessRecord pr = procs.get(i);
7452                if (pr == mHomeProcess) {
7453                    // Don't kill the home process along with tasks from the same package.
7454                    continue;
7455                }
7456                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7457                    killUnneededProcessLocked(pr, "remove task");
7458                } else {
7459                    pr.waitingToKill = "remove task";
7460                }
7461            }
7462        }
7463    }
7464
7465    /**
7466     * Removes the task with the specified task id.
7467     *
7468     * @param taskId Identifier of the task to be removed.
7469     * @param flags Additional operational flags.  May be 0 or
7470     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7471     * @return Returns true if the given task was found and removed.
7472     */
7473    private boolean removeTaskByIdLocked(int taskId, int flags) {
7474        TaskRecord tr = recentTaskForIdLocked(taskId);
7475        if (tr != null) {
7476            tr.removeTaskActivitiesLocked(-1, false);
7477            cleanUpRemovedTaskLocked(tr, flags);
7478            if (tr.isPersistable) {
7479                notifyTaskPersisterLocked(tr, true);
7480            }
7481            return true;
7482        }
7483        return false;
7484    }
7485
7486    @Override
7487    public boolean removeTask(int taskId, int flags) {
7488        synchronized (this) {
7489            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7490                    "removeTask()");
7491            long ident = Binder.clearCallingIdentity();
7492            try {
7493                return removeTaskByIdLocked(taskId, flags);
7494            } finally {
7495                Binder.restoreCallingIdentity(ident);
7496            }
7497        }
7498    }
7499
7500    /**
7501     * TODO: Add mController hook
7502     */
7503    @Override
7504    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7505        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7506                "moveTaskToFront()");
7507
7508        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7509        synchronized(this) {
7510            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7511                    Binder.getCallingUid(), "Task to front")) {
7512                ActivityOptions.abort(options);
7513                return;
7514            }
7515            final long origId = Binder.clearCallingIdentity();
7516            try {
7517                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7518                if (task == null) {
7519                    return;
7520                }
7521                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7522                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7523                    return;
7524                }
7525                final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
7526                if (prev != null && prev.isRecentsActivity()) {
7527                    task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
7528                }
7529                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7530            } finally {
7531                Binder.restoreCallingIdentity(origId);
7532            }
7533            ActivityOptions.abort(options);
7534        }
7535    }
7536
7537    @Override
7538    public void moveTaskToBack(int taskId) {
7539        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7540                "moveTaskToBack()");
7541
7542        synchronized(this) {
7543            TaskRecord tr = recentTaskForIdLocked(taskId);
7544            if (tr != null) {
7545                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7546                ActivityStack stack = tr.stack;
7547                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7548                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7549                            Binder.getCallingUid(), "Task to back")) {
7550                        return;
7551                    }
7552                }
7553                final long origId = Binder.clearCallingIdentity();
7554                try {
7555                    stack.moveTaskToBackLocked(taskId, null);
7556                } finally {
7557                    Binder.restoreCallingIdentity(origId);
7558                }
7559            }
7560        }
7561    }
7562
7563    /**
7564     * Moves an activity, and all of the other activities within the same task, to the bottom
7565     * of the history stack.  The activity's order within the task is unchanged.
7566     *
7567     * @param token A reference to the activity we wish to move
7568     * @param nonRoot If false then this only works if the activity is the root
7569     *                of a task; if true it will work for any activity in a task.
7570     * @return Returns true if the move completed, false if not.
7571     */
7572    @Override
7573    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7574        enforceNotIsolatedCaller("moveActivityTaskToBack");
7575        synchronized(this) {
7576            final long origId = Binder.clearCallingIdentity();
7577            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7578            if (taskId >= 0) {
7579                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7580            }
7581            Binder.restoreCallingIdentity(origId);
7582        }
7583        return false;
7584    }
7585
7586    @Override
7587    public void moveTaskBackwards(int task) {
7588        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7589                "moveTaskBackwards()");
7590
7591        synchronized(this) {
7592            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7593                    Binder.getCallingUid(), "Task backwards")) {
7594                return;
7595            }
7596            final long origId = Binder.clearCallingIdentity();
7597            moveTaskBackwardsLocked(task);
7598            Binder.restoreCallingIdentity(origId);
7599        }
7600    }
7601
7602    private final void moveTaskBackwardsLocked(int task) {
7603        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7604    }
7605
7606    @Override
7607    public IBinder getHomeActivityToken() throws RemoteException {
7608        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7609                "getHomeActivityToken()");
7610        synchronized (this) {
7611            return mStackSupervisor.getHomeActivityToken();
7612        }
7613    }
7614
7615    @Override
7616    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7617            IActivityContainerCallback callback) throws RemoteException {
7618        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7619                "createActivityContainer()");
7620        synchronized (this) {
7621            if (parentActivityToken == null) {
7622                throw new IllegalArgumentException("parent token must not be null");
7623            }
7624            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7625            if (r == null) {
7626                return null;
7627            }
7628            if (callback == null) {
7629                throw new IllegalArgumentException("callback must not be null");
7630            }
7631            return mStackSupervisor.createActivityContainer(r, callback);
7632        }
7633    }
7634
7635    @Override
7636    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7637        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7638                "deleteActivityContainer()");
7639        synchronized (this) {
7640            mStackSupervisor.deleteActivityContainer(container);
7641        }
7642    }
7643
7644    @Override
7645    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7646            throws RemoteException {
7647        synchronized (this) {
7648            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7649            if (stack != null) {
7650                return stack.mActivityContainer;
7651            }
7652            return null;
7653        }
7654    }
7655
7656    @Override
7657    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7658        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7659                "moveTaskToStack()");
7660        if (stackId == HOME_STACK_ID) {
7661            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7662                    new RuntimeException("here").fillInStackTrace());
7663        }
7664        synchronized (this) {
7665            long ident = Binder.clearCallingIdentity();
7666            try {
7667                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7668                        + stackId + " toTop=" + toTop);
7669                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7670            } finally {
7671                Binder.restoreCallingIdentity(ident);
7672            }
7673        }
7674    }
7675
7676    @Override
7677    public void resizeStack(int stackBoxId, Rect bounds) {
7678        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7679                "resizeStackBox()");
7680        long ident = Binder.clearCallingIdentity();
7681        try {
7682            mWindowManager.resizeStack(stackBoxId, bounds);
7683        } finally {
7684            Binder.restoreCallingIdentity(ident);
7685        }
7686    }
7687
7688    @Override
7689    public List<StackInfo> getAllStackInfos() {
7690        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7691                "getAllStackInfos()");
7692        long ident = Binder.clearCallingIdentity();
7693        try {
7694            synchronized (this) {
7695                return mStackSupervisor.getAllStackInfosLocked();
7696            }
7697        } finally {
7698            Binder.restoreCallingIdentity(ident);
7699        }
7700    }
7701
7702    @Override
7703    public StackInfo getStackInfo(int stackId) {
7704        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7705                "getStackInfo()");
7706        long ident = Binder.clearCallingIdentity();
7707        try {
7708            synchronized (this) {
7709                return mStackSupervisor.getStackInfoLocked(stackId);
7710            }
7711        } finally {
7712            Binder.restoreCallingIdentity(ident);
7713        }
7714    }
7715
7716    @Override
7717    public boolean isInHomeStack(int taskId) {
7718        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7719                "getStackInfo()");
7720        long ident = Binder.clearCallingIdentity();
7721        try {
7722            synchronized (this) {
7723                TaskRecord tr = recentTaskForIdLocked(taskId);
7724                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7725            }
7726        } finally {
7727            Binder.restoreCallingIdentity(ident);
7728        }
7729    }
7730
7731    @Override
7732    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7733        synchronized(this) {
7734            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7735        }
7736    }
7737
7738    private boolean isLockTaskAuthorized(String pkg) {
7739        final DevicePolicyManager dpm = (DevicePolicyManager)
7740                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7741        try {
7742            int uid = mContext.getPackageManager().getPackageUid(pkg,
7743                    Binder.getCallingUserHandle().getIdentifier());
7744            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
7745        } catch (NameNotFoundException e) {
7746            return false;
7747        }
7748    }
7749
7750    void startLockTaskMode(TaskRecord task) {
7751        final String pkg;
7752        synchronized (this) {
7753            pkg = task.intent.getComponent().getPackageName();
7754        }
7755        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
7756        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
7757            final TaskRecord taskRecord = task;
7758            mHandler.post(new Runnable() {
7759                @Override
7760                public void run() {
7761                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
7762                }
7763            });
7764            return;
7765        }
7766        long ident = Binder.clearCallingIdentity();
7767        try {
7768            synchronized (this) {
7769                // Since we lost lock on task, make sure it is still there.
7770                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7771                if (task != null) {
7772                    if ((mFocusedActivity == null) || (task != mFocusedActivity.task)) {
7773                        throw new IllegalArgumentException("Invalid task, not in foreground");
7774                    }
7775                    mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated);
7776                }
7777            }
7778        } finally {
7779            Binder.restoreCallingIdentity(ident);
7780        }
7781    }
7782
7783    @Override
7784    public void startLockTaskMode(int taskId) {
7785        final TaskRecord task;
7786        long ident = Binder.clearCallingIdentity();
7787        try {
7788            synchronized (this) {
7789                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7790            }
7791        } finally {
7792            Binder.restoreCallingIdentity(ident);
7793        }
7794        if (task != null) {
7795            startLockTaskMode(task);
7796        }
7797    }
7798
7799    @Override
7800    public void startLockTaskMode(IBinder token) {
7801        final TaskRecord task;
7802        long ident = Binder.clearCallingIdentity();
7803        try {
7804            synchronized (this) {
7805                final ActivityRecord r = ActivityRecord.forToken(token);
7806                if (r == null) {
7807                    return;
7808                }
7809                task = r.task;
7810            }
7811        } finally {
7812            Binder.restoreCallingIdentity(ident);
7813        }
7814        if (task != null) {
7815            startLockTaskMode(task);
7816        }
7817    }
7818
7819    @Override
7820    public void startLockTaskModeOnCurrent() throws RemoteException {
7821        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7822        ActivityRecord r = null;
7823        synchronized (this) {
7824            r = mStackSupervisor.topRunningActivityLocked();
7825        }
7826        startLockTaskMode(r.task);
7827    }
7828
7829    @Override
7830    public void stopLockTaskMode() {
7831        // Verify that the user matches the package of the intent for the TaskRecord
7832        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
7833        // and stopLockTaskMode.
7834        final int callingUid = Binder.getCallingUid();
7835        if (callingUid != Process.SYSTEM_UID) {
7836            try {
7837                String pkg =
7838                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
7839                int uid = mContext.getPackageManager().getPackageUid(pkg,
7840                        Binder.getCallingUserHandle().getIdentifier());
7841                if (uid != callingUid) {
7842                    throw new SecurityException("Invalid uid, expected " + uid);
7843                }
7844            } catch (NameNotFoundException e) {
7845                Log.d(TAG, "stopLockTaskMode " + e);
7846                return;
7847            }
7848        }
7849        long ident = Binder.clearCallingIdentity();
7850        try {
7851            Log.d(TAG, "stopLockTaskMode");
7852            // Stop lock task
7853            synchronized (this) {
7854                mStackSupervisor.setLockTaskModeLocked(null, false);
7855            }
7856        } finally {
7857            Binder.restoreCallingIdentity(ident);
7858        }
7859    }
7860
7861    @Override
7862    public void stopLockTaskModeOnCurrent() throws RemoteException {
7863        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7864        long ident = Binder.clearCallingIdentity();
7865        try {
7866            stopLockTaskMode();
7867        } finally {
7868            Binder.restoreCallingIdentity(ident);
7869        }
7870    }
7871
7872    @Override
7873    public boolean isInLockTaskMode() {
7874        synchronized (this) {
7875            return mStackSupervisor.isInLockTaskMode();
7876        }
7877    }
7878
7879    // =========================================================
7880    // CONTENT PROVIDERS
7881    // =========================================================
7882
7883    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7884        List<ProviderInfo> providers = null;
7885        try {
7886            providers = AppGlobals.getPackageManager().
7887                queryContentProviders(app.processName, app.uid,
7888                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7889        } catch (RemoteException ex) {
7890        }
7891        if (DEBUG_MU)
7892            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7893        int userId = app.userId;
7894        if (providers != null) {
7895            int N = providers.size();
7896            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7897            for (int i=0; i<N; i++) {
7898                ProviderInfo cpi =
7899                    (ProviderInfo)providers.get(i);
7900                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7901                        cpi.name, cpi.flags);
7902                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7903                    // This is a singleton provider, but a user besides the
7904                    // default user is asking to initialize a process it runs
7905                    // in...  well, no, it doesn't actually run in this process,
7906                    // it runs in the process of the default user.  Get rid of it.
7907                    providers.remove(i);
7908                    N--;
7909                    i--;
7910                    continue;
7911                }
7912
7913                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7914                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7915                if (cpr == null) {
7916                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7917                    mProviderMap.putProviderByClass(comp, cpr);
7918                }
7919                if (DEBUG_MU)
7920                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7921                app.pubProviders.put(cpi.name, cpr);
7922                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7923                    // Don't add this if it is a platform component that is marked
7924                    // to run in multiple processes, because this is actually
7925                    // part of the framework so doesn't make sense to track as a
7926                    // separate apk in the process.
7927                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
7928                            mProcessStats);
7929                }
7930                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7931            }
7932        }
7933        return providers;
7934    }
7935
7936    /**
7937     * Check if {@link ProcessRecord} has a possible chance at accessing the
7938     * given {@link ProviderInfo}. Final permission checking is always done
7939     * in {@link ContentProvider}.
7940     */
7941    private final String checkContentProviderPermissionLocked(
7942            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
7943        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7944        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7945        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7946        // Looking for cross-user grants before to enforce the typical cross-users permissions
7947        if (userId != UserHandle.getUserId(callingUid)) {
7948            if (perms != null) {
7949                for (GrantUri grantUri : perms.keySet()) {
7950                    if (grantUri.sourceUserId == userId) {
7951                        String authority = grantUri.uri.getAuthority();
7952                        if (authority.equals(cpi.authority)) {
7953                            return null;
7954                        }
7955                    }
7956                }
7957            }
7958        }
7959        if (checkUser) {
7960            userId = handleIncomingUser(callingPid, callingUid, userId,
7961                    false, true, "checkContentProviderPermissionLocked " + cpi.authority, null);
7962        }
7963        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7964                cpi.applicationInfo.uid, cpi.exported)
7965                == PackageManager.PERMISSION_GRANTED) {
7966            return null;
7967        }
7968        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7969                cpi.applicationInfo.uid, cpi.exported)
7970                == PackageManager.PERMISSION_GRANTED) {
7971            return null;
7972        }
7973
7974        PathPermission[] pps = cpi.pathPermissions;
7975        if (pps != null) {
7976            int i = pps.length;
7977            while (i > 0) {
7978                i--;
7979                PathPermission pp = pps[i];
7980                if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
7981                        cpi.applicationInfo.uid, cpi.exported)
7982                        == PackageManager.PERMISSION_GRANTED) {
7983                    return null;
7984                }
7985                if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
7986                        cpi.applicationInfo.uid, cpi.exported)
7987                        == PackageManager.PERMISSION_GRANTED) {
7988                    return null;
7989                }
7990            }
7991        }
7992
7993        if (perms != null) {
7994            for (GrantUri grantUri : perms.keySet()) {
7995                if (grantUri.uri.getAuthority().equals(cpi.authority)) {
7996                    return null;
7997                }
7998            }
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    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8018            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8019        if (r != null) {
8020            for (int i=0; i<r.conProviders.size(); i++) {
8021                ContentProviderConnection conn = r.conProviders.get(i);
8022                if (conn.provider == cpr) {
8023                    if (DEBUG_PROVIDER) Slog.v(TAG,
8024                            "Adding provider requested by "
8025                            + r.processName + " from process "
8026                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8027                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8028                    if (stable) {
8029                        conn.stableCount++;
8030                        conn.numStableIncs++;
8031                    } else {
8032                        conn.unstableCount++;
8033                        conn.numUnstableIncs++;
8034                    }
8035                    return conn;
8036                }
8037            }
8038            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8039            if (stable) {
8040                conn.stableCount = 1;
8041                conn.numStableIncs = 1;
8042            } else {
8043                conn.unstableCount = 1;
8044                conn.numUnstableIncs = 1;
8045            }
8046            cpr.connections.add(conn);
8047            r.conProviders.add(conn);
8048            return conn;
8049        }
8050        cpr.addExternalProcessHandleLocked(externalProcessToken);
8051        return null;
8052    }
8053
8054    boolean decProviderCountLocked(ContentProviderConnection conn,
8055            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8056        if (conn != null) {
8057            cpr = conn.provider;
8058            if (DEBUG_PROVIDER) Slog.v(TAG,
8059                    "Removing provider requested by "
8060                    + conn.client.processName + " from process "
8061                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8062                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8063            if (stable) {
8064                conn.stableCount--;
8065            } else {
8066                conn.unstableCount--;
8067            }
8068            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8069                cpr.connections.remove(conn);
8070                conn.client.conProviders.remove(conn);
8071                return true;
8072            }
8073            return false;
8074        }
8075        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8076        return false;
8077    }
8078
8079    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8080            String name, IBinder token, boolean stable, int userId) {
8081        ContentProviderRecord cpr;
8082        ContentProviderConnection conn = null;
8083        ProviderInfo cpi = null;
8084
8085        synchronized(this) {
8086            ProcessRecord r = null;
8087            if (caller != null) {
8088                r = getRecordForAppLocked(caller);
8089                if (r == null) {
8090                    throw new SecurityException(
8091                            "Unable to find app for caller " + caller
8092                          + " (pid=" + Binder.getCallingPid()
8093                          + ") when getting content provider " + name);
8094                }
8095            }
8096
8097            boolean checkCrossUser = true;
8098
8099            // First check if this content provider has been published...
8100            cpr = mProviderMap.getProviderByName(name, userId);
8101            // If that didn't work, check if it exists for user 0 and then
8102            // verify that it's a singleton provider before using it.
8103            if (cpr == null && userId != UserHandle.USER_OWNER) {
8104                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8105                if (cpr != null) {
8106                    cpi = cpr.info;
8107                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8108                            cpi.name, cpi.flags)
8109                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8110                        userId = UserHandle.USER_OWNER;
8111                        checkCrossUser = false;
8112                    } else {
8113                        cpr = null;
8114                        cpi = null;
8115                    }
8116                }
8117            }
8118
8119            boolean providerRunning = cpr != null;
8120            if (providerRunning) {
8121                cpi = cpr.info;
8122                String msg;
8123                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8124                        != null) {
8125                    throw new SecurityException(msg);
8126                }
8127
8128                if (r != null && cpr.canRunHere(r)) {
8129                    // This provider has been published or is in the process
8130                    // of being published...  but it is also allowed to run
8131                    // in the caller's process, so don't make a connection
8132                    // and just let the caller instantiate its own instance.
8133                    ContentProviderHolder holder = cpr.newHolder(null);
8134                    // don't give caller the provider object, it needs
8135                    // to make its own.
8136                    holder.provider = null;
8137                    return holder;
8138                }
8139
8140                final long origId = Binder.clearCallingIdentity();
8141
8142                // In this case the provider instance already exists, so we can
8143                // return it right away.
8144                conn = incProviderCountLocked(r, cpr, token, stable);
8145                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8146                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8147                        // If this is a perceptible app accessing the provider,
8148                        // make sure to count it as being accessed and thus
8149                        // back up on the LRU list.  This is good because
8150                        // content providers are often expensive to start.
8151                        updateLruProcessLocked(cpr.proc, false, null);
8152                    }
8153                }
8154
8155                if (cpr.proc != null) {
8156                    if (false) {
8157                        if (cpr.name.flattenToShortString().equals(
8158                                "com.android.providers.calendar/.CalendarProvider2")) {
8159                            Slog.v(TAG, "****************** KILLING "
8160                                + cpr.name.flattenToShortString());
8161                            Process.killProcess(cpr.proc.pid);
8162                        }
8163                    }
8164                    boolean success = updateOomAdjLocked(cpr.proc);
8165                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8166                    // NOTE: there is still a race here where a signal could be
8167                    // pending on the process even though we managed to update its
8168                    // adj level.  Not sure what to do about this, but at least
8169                    // the race is now smaller.
8170                    if (!success) {
8171                        // Uh oh...  it looks like the provider's process
8172                        // has been killed on us.  We need to wait for a new
8173                        // process to be started, and make sure its death
8174                        // doesn't kill our process.
8175                        Slog.i(TAG,
8176                                "Existing provider " + cpr.name.flattenToShortString()
8177                                + " is crashing; detaching " + r);
8178                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8179                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8180                        if (!lastRef) {
8181                            // This wasn't the last ref our process had on
8182                            // the provider...  we have now been killed, bail.
8183                            return null;
8184                        }
8185                        providerRunning = false;
8186                        conn = null;
8187                    }
8188                }
8189
8190                Binder.restoreCallingIdentity(origId);
8191            }
8192
8193            boolean singleton;
8194            if (!providerRunning) {
8195                try {
8196                    cpi = AppGlobals.getPackageManager().
8197                        resolveContentProvider(name,
8198                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8199                } catch (RemoteException ex) {
8200                }
8201                if (cpi == null) {
8202                    return null;
8203                }
8204                // If the provider is a singleton AND
8205                // (it's a call within the same user || the provider is a
8206                // privileged app)
8207                // Then allow connecting to the singleton provider
8208                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8209                        cpi.name, cpi.flags)
8210                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8211                if (singleton) {
8212                    userId = UserHandle.USER_OWNER;
8213                }
8214                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8215
8216                String msg;
8217                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8218                        != null) {
8219                    throw new SecurityException(msg);
8220                }
8221
8222                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8223                        && !cpi.processName.equals("system")) {
8224                    // If this content provider does not run in the system
8225                    // process, and the system is not yet ready to run other
8226                    // processes, then fail fast instead of hanging.
8227                    throw new IllegalArgumentException(
8228                            "Attempt to launch content provider before system ready");
8229                }
8230
8231                // Make sure that the user who owns this provider is started.  If not,
8232                // we don't want to allow it to run.
8233                if (mStartedUsers.get(userId) == null) {
8234                    Slog.w(TAG, "Unable to launch app "
8235                            + cpi.applicationInfo.packageName + "/"
8236                            + cpi.applicationInfo.uid + " for provider "
8237                            + name + ": user " + userId + " is stopped");
8238                    return null;
8239                }
8240
8241                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8242                cpr = mProviderMap.getProviderByClass(comp, userId);
8243                final boolean firstClass = cpr == null;
8244                if (firstClass) {
8245                    try {
8246                        ApplicationInfo ai =
8247                            AppGlobals.getPackageManager().
8248                                getApplicationInfo(
8249                                        cpi.applicationInfo.packageName,
8250                                        STOCK_PM_FLAGS, userId);
8251                        if (ai == null) {
8252                            Slog.w(TAG, "No package info for content provider "
8253                                    + cpi.name);
8254                            return null;
8255                        }
8256                        ai = getAppInfoForUser(ai, userId);
8257                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8258                    } catch (RemoteException ex) {
8259                        // pm is in same process, this will never happen.
8260                    }
8261                }
8262
8263                if (r != null && cpr.canRunHere(r)) {
8264                    // If this is a multiprocess provider, then just return its
8265                    // info and allow the caller to instantiate it.  Only do
8266                    // this if the provider is the same user as the caller's
8267                    // process, or can run as root (so can be in any process).
8268                    return cpr.newHolder(null);
8269                }
8270
8271                if (DEBUG_PROVIDER) {
8272                    RuntimeException e = new RuntimeException("here");
8273                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8274                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8275                }
8276
8277                // This is single process, and our app is now connecting to it.
8278                // See if we are already in the process of launching this
8279                // provider.
8280                final int N = mLaunchingProviders.size();
8281                int i;
8282                for (i=0; i<N; i++) {
8283                    if (mLaunchingProviders.get(i) == cpr) {
8284                        break;
8285                    }
8286                }
8287
8288                // If the provider is not already being launched, then get it
8289                // started.
8290                if (i >= N) {
8291                    final long origId = Binder.clearCallingIdentity();
8292
8293                    try {
8294                        // Content provider is now in use, its package can't be stopped.
8295                        try {
8296                            AppGlobals.getPackageManager().setPackageStoppedState(
8297                                    cpr.appInfo.packageName, false, userId);
8298                        } catch (RemoteException e) {
8299                        } catch (IllegalArgumentException e) {
8300                            Slog.w(TAG, "Failed trying to unstop package "
8301                                    + cpr.appInfo.packageName + ": " + e);
8302                        }
8303
8304                        // Use existing process if already started
8305                        ProcessRecord proc = getProcessRecordLocked(
8306                                cpi.processName, cpr.appInfo.uid, false);
8307                        if (proc != null && proc.thread != null) {
8308                            if (DEBUG_PROVIDER) {
8309                                Slog.d(TAG, "Installing in existing process " + proc);
8310                            }
8311                            proc.pubProviders.put(cpi.name, cpr);
8312                            try {
8313                                proc.thread.scheduleInstallProvider(cpi);
8314                            } catch (RemoteException e) {
8315                            }
8316                        } else {
8317                            proc = startProcessLocked(cpi.processName,
8318                                    cpr.appInfo, false, 0, "content provider",
8319                                    new ComponentName(cpi.applicationInfo.packageName,
8320                                            cpi.name), false, false, false);
8321                            if (proc == null) {
8322                                Slog.w(TAG, "Unable to launch app "
8323                                        + cpi.applicationInfo.packageName + "/"
8324                                        + cpi.applicationInfo.uid + " for provider "
8325                                        + name + ": process is bad");
8326                                return null;
8327                            }
8328                        }
8329                        cpr.launchingApp = proc;
8330                        mLaunchingProviders.add(cpr);
8331                    } finally {
8332                        Binder.restoreCallingIdentity(origId);
8333                    }
8334                }
8335
8336                // Make sure the provider is published (the same provider class
8337                // may be published under multiple names).
8338                if (firstClass) {
8339                    mProviderMap.putProviderByClass(comp, cpr);
8340                }
8341
8342                mProviderMap.putProviderByName(name, cpr);
8343                conn = incProviderCountLocked(r, cpr, token, stable);
8344                if (conn != null) {
8345                    conn.waiting = true;
8346                }
8347            }
8348        }
8349
8350        // Wait for the provider to be published...
8351        synchronized (cpr) {
8352            while (cpr.provider == null) {
8353                if (cpr.launchingApp == null) {
8354                    Slog.w(TAG, "Unable to launch app "
8355                            + cpi.applicationInfo.packageName + "/"
8356                            + cpi.applicationInfo.uid + " for provider "
8357                            + name + ": launching app became null");
8358                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8359                            UserHandle.getUserId(cpi.applicationInfo.uid),
8360                            cpi.applicationInfo.packageName,
8361                            cpi.applicationInfo.uid, name);
8362                    return null;
8363                }
8364                try {
8365                    if (DEBUG_MU) {
8366                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8367                                + cpr.launchingApp);
8368                    }
8369                    if (conn != null) {
8370                        conn.waiting = true;
8371                    }
8372                    cpr.wait();
8373                } catch (InterruptedException ex) {
8374                } finally {
8375                    if (conn != null) {
8376                        conn.waiting = false;
8377                    }
8378                }
8379            }
8380        }
8381        return cpr != null ? cpr.newHolder(conn) : null;
8382    }
8383
8384    @Override
8385    public final ContentProviderHolder getContentProvider(
8386            IApplicationThread caller, String name, int userId, boolean stable) {
8387        enforceNotIsolatedCaller("getContentProvider");
8388        if (caller == null) {
8389            String msg = "null IApplicationThread when getting content provider "
8390                    + name;
8391            Slog.w(TAG, msg);
8392            throw new SecurityException(msg);
8393        }
8394        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8395        // with cross-user grant.
8396        return getContentProviderImpl(caller, name, null, stable, userId);
8397    }
8398
8399    public ContentProviderHolder getContentProviderExternal(
8400            String name, int userId, IBinder token) {
8401        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8402            "Do not have permission in call getContentProviderExternal()");
8403        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8404                false, true, "getContentProvider", null);
8405        return getContentProviderExternalUnchecked(name, token, userId);
8406    }
8407
8408    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8409            IBinder token, int userId) {
8410        return getContentProviderImpl(null, name, token, true, userId);
8411    }
8412
8413    /**
8414     * Drop a content provider from a ProcessRecord's bookkeeping
8415     */
8416    public void removeContentProvider(IBinder connection, boolean stable) {
8417        enforceNotIsolatedCaller("removeContentProvider");
8418        long ident = Binder.clearCallingIdentity();
8419        try {
8420            synchronized (this) {
8421                ContentProviderConnection conn;
8422                try {
8423                    conn = (ContentProviderConnection)connection;
8424                } catch (ClassCastException e) {
8425                    String msg ="removeContentProvider: " + connection
8426                            + " not a ContentProviderConnection";
8427                    Slog.w(TAG, msg);
8428                    throw new IllegalArgumentException(msg);
8429                }
8430                if (conn == null) {
8431                    throw new NullPointerException("connection is null");
8432                }
8433                if (decProviderCountLocked(conn, null, null, stable)) {
8434                    updateOomAdjLocked();
8435                }
8436            }
8437        } finally {
8438            Binder.restoreCallingIdentity(ident);
8439        }
8440    }
8441
8442    public void removeContentProviderExternal(String name, IBinder token) {
8443        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8444            "Do not have permission in call removeContentProviderExternal()");
8445        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8446    }
8447
8448    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8449        synchronized (this) {
8450            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8451            if(cpr == null) {
8452                //remove from mProvidersByClass
8453                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8454                return;
8455            }
8456
8457            //update content provider record entry info
8458            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8459            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8460            if (localCpr.hasExternalProcessHandles()) {
8461                if (localCpr.removeExternalProcessHandleLocked(token)) {
8462                    updateOomAdjLocked();
8463                } else {
8464                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8465                            + " with no external reference for token: "
8466                            + token + ".");
8467                }
8468            } else {
8469                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8470                        + " with no external references.");
8471            }
8472        }
8473    }
8474
8475    public final void publishContentProviders(IApplicationThread caller,
8476            List<ContentProviderHolder> providers) {
8477        if (providers == null) {
8478            return;
8479        }
8480
8481        enforceNotIsolatedCaller("publishContentProviders");
8482        synchronized (this) {
8483            final ProcessRecord r = getRecordForAppLocked(caller);
8484            if (DEBUG_MU)
8485                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8486            if (r == null) {
8487                throw new SecurityException(
8488                        "Unable to find app for caller " + caller
8489                      + " (pid=" + Binder.getCallingPid()
8490                      + ") when publishing content providers");
8491            }
8492
8493            final long origId = Binder.clearCallingIdentity();
8494
8495            final int N = providers.size();
8496            for (int i=0; i<N; i++) {
8497                ContentProviderHolder src = providers.get(i);
8498                if (src == null || src.info == null || src.provider == null) {
8499                    continue;
8500                }
8501                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8502                if (DEBUG_MU)
8503                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8504                if (dst != null) {
8505                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8506                    mProviderMap.putProviderByClass(comp, dst);
8507                    String names[] = dst.info.authority.split(";");
8508                    for (int j = 0; j < names.length; j++) {
8509                        mProviderMap.putProviderByName(names[j], dst);
8510                    }
8511
8512                    int NL = mLaunchingProviders.size();
8513                    int j;
8514                    for (j=0; j<NL; j++) {
8515                        if (mLaunchingProviders.get(j) == dst) {
8516                            mLaunchingProviders.remove(j);
8517                            j--;
8518                            NL--;
8519                        }
8520                    }
8521                    synchronized (dst) {
8522                        dst.provider = src.provider;
8523                        dst.proc = r;
8524                        dst.notifyAll();
8525                    }
8526                    updateOomAdjLocked(r);
8527                }
8528            }
8529
8530            Binder.restoreCallingIdentity(origId);
8531        }
8532    }
8533
8534    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8535        ContentProviderConnection conn;
8536        try {
8537            conn = (ContentProviderConnection)connection;
8538        } catch (ClassCastException e) {
8539            String msg ="refContentProvider: " + connection
8540                    + " not a ContentProviderConnection";
8541            Slog.w(TAG, msg);
8542            throw new IllegalArgumentException(msg);
8543        }
8544        if (conn == null) {
8545            throw new NullPointerException("connection is null");
8546        }
8547
8548        synchronized (this) {
8549            if (stable > 0) {
8550                conn.numStableIncs += stable;
8551            }
8552            stable = conn.stableCount + stable;
8553            if (stable < 0) {
8554                throw new IllegalStateException("stableCount < 0: " + stable);
8555            }
8556
8557            if (unstable > 0) {
8558                conn.numUnstableIncs += unstable;
8559            }
8560            unstable = conn.unstableCount + unstable;
8561            if (unstable < 0) {
8562                throw new IllegalStateException("unstableCount < 0: " + unstable);
8563            }
8564
8565            if ((stable+unstable) <= 0) {
8566                throw new IllegalStateException("ref counts can't go to zero here: stable="
8567                        + stable + " unstable=" + unstable);
8568            }
8569            conn.stableCount = stable;
8570            conn.unstableCount = unstable;
8571            return !conn.dead;
8572        }
8573    }
8574
8575    public void unstableProviderDied(IBinder connection) {
8576        ContentProviderConnection conn;
8577        try {
8578            conn = (ContentProviderConnection)connection;
8579        } catch (ClassCastException e) {
8580            String msg ="refContentProvider: " + connection
8581                    + " not a ContentProviderConnection";
8582            Slog.w(TAG, msg);
8583            throw new IllegalArgumentException(msg);
8584        }
8585        if (conn == null) {
8586            throw new NullPointerException("connection is null");
8587        }
8588
8589        // Safely retrieve the content provider associated with the connection.
8590        IContentProvider provider;
8591        synchronized (this) {
8592            provider = conn.provider.provider;
8593        }
8594
8595        if (provider == null) {
8596            // Um, yeah, we're way ahead of you.
8597            return;
8598        }
8599
8600        // Make sure the caller is being honest with us.
8601        if (provider.asBinder().pingBinder()) {
8602            // Er, no, still looks good to us.
8603            synchronized (this) {
8604                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8605                        + " says " + conn + " died, but we don't agree");
8606                return;
8607            }
8608        }
8609
8610        // Well look at that!  It's dead!
8611        synchronized (this) {
8612            if (conn.provider.provider != provider) {
8613                // But something changed...  good enough.
8614                return;
8615            }
8616
8617            ProcessRecord proc = conn.provider.proc;
8618            if (proc == null || proc.thread == null) {
8619                // Seems like the process is already cleaned up.
8620                return;
8621            }
8622
8623            // As far as we're concerned, this is just like receiving a
8624            // death notification...  just a bit prematurely.
8625            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8626                    + ") early provider death");
8627            final long ident = Binder.clearCallingIdentity();
8628            try {
8629                appDiedLocked(proc, proc.pid, proc.thread);
8630            } finally {
8631                Binder.restoreCallingIdentity(ident);
8632            }
8633        }
8634    }
8635
8636    @Override
8637    public void appNotRespondingViaProvider(IBinder connection) {
8638        enforceCallingPermission(
8639                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8640
8641        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8642        if (conn == null) {
8643            Slog.w(TAG, "ContentProviderConnection is null");
8644            return;
8645        }
8646
8647        final ProcessRecord host = conn.provider.proc;
8648        if (host == null) {
8649            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8650            return;
8651        }
8652
8653        final long token = Binder.clearCallingIdentity();
8654        try {
8655            appNotResponding(host, null, null, false, "ContentProvider not responding");
8656        } finally {
8657            Binder.restoreCallingIdentity(token);
8658        }
8659    }
8660
8661    public final void installSystemProviders() {
8662        List<ProviderInfo> providers;
8663        synchronized (this) {
8664            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8665            providers = generateApplicationProvidersLocked(app);
8666            if (providers != null) {
8667                for (int i=providers.size()-1; i>=0; i--) {
8668                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8669                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8670                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8671                                + ": not system .apk");
8672                        providers.remove(i);
8673                    }
8674                }
8675            }
8676        }
8677        if (providers != null) {
8678            mSystemThread.installSystemProviders(providers);
8679        }
8680
8681        mCoreSettingsObserver = new CoreSettingsObserver(this);
8682
8683        mUsageStatsService.monitorPackages();
8684    }
8685
8686    /**
8687     * Allows app to retrieve the MIME type of a URI without having permission
8688     * to access its content provider.
8689     *
8690     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8691     *
8692     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8693     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8694     */
8695    public String getProviderMimeType(Uri uri, int userId) {
8696        enforceNotIsolatedCaller("getProviderMimeType");
8697        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8698                userId, false, true, "getProviderMimeType", null);
8699        final String name = uri.getAuthority();
8700        final long ident = Binder.clearCallingIdentity();
8701        ContentProviderHolder holder = null;
8702
8703        try {
8704            holder = getContentProviderExternalUnchecked(name, null, userId);
8705            if (holder != null) {
8706                return holder.provider.getType(uri);
8707            }
8708        } catch (RemoteException e) {
8709            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8710            return null;
8711        } finally {
8712            if (holder != null) {
8713                removeContentProviderExternalUnchecked(name, null, userId);
8714            }
8715            Binder.restoreCallingIdentity(ident);
8716        }
8717
8718        return null;
8719    }
8720
8721    // =========================================================
8722    // GLOBAL MANAGEMENT
8723    // =========================================================
8724
8725    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8726            boolean isolated) {
8727        String proc = customProcess != null ? customProcess : info.processName;
8728        BatteryStatsImpl.Uid.Proc ps = null;
8729        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8730        int uid = info.uid;
8731        if (isolated) {
8732            int userId = UserHandle.getUserId(uid);
8733            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8734            while (true) {
8735                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8736                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8737                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8738                }
8739                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8740                mNextIsolatedProcessUid++;
8741                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8742                    // No process for this uid, use it.
8743                    break;
8744                }
8745                stepsLeft--;
8746                if (stepsLeft <= 0) {
8747                    return null;
8748                }
8749            }
8750        }
8751        return new ProcessRecord(stats, info, proc, uid);
8752    }
8753
8754    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
8755            String abiOverride) {
8756        ProcessRecord app;
8757        if (!isolated) {
8758            app = getProcessRecordLocked(info.processName, info.uid, true);
8759        } else {
8760            app = null;
8761        }
8762
8763        if (app == null) {
8764            app = newProcessRecordLocked(info, null, isolated);
8765            mProcessNames.put(info.processName, app.uid, app);
8766            if (isolated) {
8767                mIsolatedProcesses.put(app.uid, app);
8768            }
8769            updateLruProcessLocked(app, false, null);
8770            updateOomAdjLocked();
8771        }
8772
8773        // This package really, really can not be stopped.
8774        try {
8775            AppGlobals.getPackageManager().setPackageStoppedState(
8776                    info.packageName, false, UserHandle.getUserId(app.uid));
8777        } catch (RemoteException e) {
8778        } catch (IllegalArgumentException e) {
8779            Slog.w(TAG, "Failed trying to unstop package "
8780                    + info.packageName + ": " + e);
8781        }
8782
8783        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8784                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8785            app.persistent = true;
8786            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8787        }
8788        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8789            mPersistentStartingProcesses.add(app);
8790            startProcessLocked(app, "added application", app.processName,
8791                    abiOverride);
8792        }
8793
8794        return app;
8795    }
8796
8797    public void unhandledBack() {
8798        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8799                "unhandledBack()");
8800
8801        synchronized(this) {
8802            final long origId = Binder.clearCallingIdentity();
8803            try {
8804                getFocusedStack().unhandledBackLocked();
8805            } finally {
8806                Binder.restoreCallingIdentity(origId);
8807            }
8808        }
8809    }
8810
8811    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8812        enforceNotIsolatedCaller("openContentUri");
8813        final int userId = UserHandle.getCallingUserId();
8814        String name = uri.getAuthority();
8815        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8816        ParcelFileDescriptor pfd = null;
8817        if (cph != null) {
8818            // We record the binder invoker's uid in thread-local storage before
8819            // going to the content provider to open the file.  Later, in the code
8820            // that handles all permissions checks, we look for this uid and use
8821            // that rather than the Activity Manager's own uid.  The effect is that
8822            // we do the check against the caller's permissions even though it looks
8823            // to the content provider like the Activity Manager itself is making
8824            // the request.
8825            sCallerIdentity.set(new Identity(
8826                    Binder.getCallingPid(), Binder.getCallingUid()));
8827            try {
8828                pfd = cph.provider.openFile(null, uri, "r", null);
8829            } catch (FileNotFoundException e) {
8830                // do nothing; pfd will be returned null
8831            } finally {
8832                // Ensure that whatever happens, we clean up the identity state
8833                sCallerIdentity.remove();
8834            }
8835
8836            // We've got the fd now, so we're done with the provider.
8837            removeContentProviderExternalUnchecked(name, null, userId);
8838        } else {
8839            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8840        }
8841        return pfd;
8842    }
8843
8844    // Actually is sleeping or shutting down or whatever else in the future
8845    // is an inactive state.
8846    public boolean isSleepingOrShuttingDown() {
8847        return mSleeping || mShuttingDown;
8848    }
8849
8850    public boolean isSleeping() {
8851        return mSleeping;
8852    }
8853
8854    void goingToSleep() {
8855        synchronized(this) {
8856            mWentToSleep = true;
8857            updateEventDispatchingLocked();
8858            goToSleepIfNeededLocked();
8859        }
8860    }
8861
8862    void finishRunningVoiceLocked() {
8863        if (mRunningVoice) {
8864            mRunningVoice = false;
8865            goToSleepIfNeededLocked();
8866        }
8867    }
8868
8869    void goToSleepIfNeededLocked() {
8870        if (mWentToSleep && !mRunningVoice) {
8871            if (!mSleeping) {
8872                mSleeping = true;
8873                mStackSupervisor.goingToSleepLocked();
8874
8875                // Initialize the wake times of all processes.
8876                checkExcessivePowerUsageLocked(false);
8877                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8878                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8879                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8880            }
8881        }
8882    }
8883
8884    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
8885        mTaskPersister.notify(task, flush);
8886    }
8887
8888    @Override
8889    public boolean shutdown(int timeout) {
8890        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8891                != PackageManager.PERMISSION_GRANTED) {
8892            throw new SecurityException("Requires permission "
8893                    + android.Manifest.permission.SHUTDOWN);
8894        }
8895
8896        boolean timedout = false;
8897
8898        synchronized(this) {
8899            mShuttingDown = true;
8900            updateEventDispatchingLocked();
8901            timedout = mStackSupervisor.shutdownLocked(timeout);
8902        }
8903
8904        mAppOpsService.shutdown();
8905        mUsageStatsService.shutdown();
8906        mBatteryStatsService.shutdown();
8907        synchronized (this) {
8908            mProcessStats.shutdownLocked();
8909        }
8910        notifyTaskPersisterLocked(null, true);
8911
8912        return timedout;
8913    }
8914
8915    public final void activitySlept(IBinder token) {
8916        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8917
8918        final long origId = Binder.clearCallingIdentity();
8919
8920        synchronized (this) {
8921            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8922            if (r != null) {
8923                mStackSupervisor.activitySleptLocked(r);
8924            }
8925        }
8926
8927        Binder.restoreCallingIdentity(origId);
8928    }
8929
8930    void logLockScreen(String msg) {
8931        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8932                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8933                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8934                mStackSupervisor.mDismissKeyguardOnNextActivity);
8935    }
8936
8937    private void comeOutOfSleepIfNeededLocked() {
8938        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
8939            if (mSleeping) {
8940                mSleeping = false;
8941                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8942            }
8943        }
8944    }
8945
8946    void wakingUp() {
8947        synchronized(this) {
8948            mWentToSleep = false;
8949            updateEventDispatchingLocked();
8950            comeOutOfSleepIfNeededLocked();
8951        }
8952    }
8953
8954    void startRunningVoiceLocked() {
8955        if (!mRunningVoice) {
8956            mRunningVoice = true;
8957            comeOutOfSleepIfNeededLocked();
8958        }
8959    }
8960
8961    private void updateEventDispatchingLocked() {
8962        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8963    }
8964
8965    public void setLockScreenShown(boolean shown) {
8966        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8967                != PackageManager.PERMISSION_GRANTED) {
8968            throw new SecurityException("Requires permission "
8969                    + android.Manifest.permission.DEVICE_POWER);
8970        }
8971
8972        synchronized(this) {
8973            long ident = Binder.clearCallingIdentity();
8974            try {
8975                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8976                mLockScreenShown = shown;
8977                comeOutOfSleepIfNeededLocked();
8978            } finally {
8979                Binder.restoreCallingIdentity(ident);
8980            }
8981        }
8982    }
8983
8984    public void stopAppSwitches() {
8985        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8986                != PackageManager.PERMISSION_GRANTED) {
8987            throw new SecurityException("Requires permission "
8988                    + android.Manifest.permission.STOP_APP_SWITCHES);
8989        }
8990
8991        synchronized(this) {
8992            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8993                    + APP_SWITCH_DELAY_TIME;
8994            mDidAppSwitch = false;
8995            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8996            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
8997            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
8998        }
8999    }
9000
9001    public void resumeAppSwitches() {
9002        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9003                != PackageManager.PERMISSION_GRANTED) {
9004            throw new SecurityException("Requires permission "
9005                    + android.Manifest.permission.STOP_APP_SWITCHES);
9006        }
9007
9008        synchronized(this) {
9009            // Note that we don't execute any pending app switches... we will
9010            // let those wait until either the timeout, or the next start
9011            // activity request.
9012            mAppSwitchesAllowedTime = 0;
9013        }
9014    }
9015
9016    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9017            String name) {
9018        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9019            return true;
9020        }
9021
9022        final int perm = checkComponentPermission(
9023                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9024                callingUid, -1, true);
9025        if (perm == PackageManager.PERMISSION_GRANTED) {
9026            return true;
9027        }
9028
9029        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9030        return false;
9031    }
9032
9033    public void setDebugApp(String packageName, boolean waitForDebugger,
9034            boolean persistent) {
9035        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9036                "setDebugApp()");
9037
9038        long ident = Binder.clearCallingIdentity();
9039        try {
9040            // Note that this is not really thread safe if there are multiple
9041            // callers into it at the same time, but that's not a situation we
9042            // care about.
9043            if (persistent) {
9044                final ContentResolver resolver = mContext.getContentResolver();
9045                Settings.Global.putString(
9046                    resolver, Settings.Global.DEBUG_APP,
9047                    packageName);
9048                Settings.Global.putInt(
9049                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9050                    waitForDebugger ? 1 : 0);
9051            }
9052
9053            synchronized (this) {
9054                if (!persistent) {
9055                    mOrigDebugApp = mDebugApp;
9056                    mOrigWaitForDebugger = mWaitForDebugger;
9057                }
9058                mDebugApp = packageName;
9059                mWaitForDebugger = waitForDebugger;
9060                mDebugTransient = !persistent;
9061                if (packageName != null) {
9062                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9063                            false, UserHandle.USER_ALL, "set debug app");
9064                }
9065            }
9066        } finally {
9067            Binder.restoreCallingIdentity(ident);
9068        }
9069    }
9070
9071    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9072        synchronized (this) {
9073            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9074            if (!isDebuggable) {
9075                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9076                    throw new SecurityException("Process not debuggable: " + app.packageName);
9077                }
9078            }
9079
9080            mOpenGlTraceApp = processName;
9081        }
9082    }
9083
9084    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9085            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9086        synchronized (this) {
9087            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9088            if (!isDebuggable) {
9089                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9090                    throw new SecurityException("Process not debuggable: " + app.packageName);
9091                }
9092            }
9093            mProfileApp = processName;
9094            mProfileFile = profileFile;
9095            if (mProfileFd != null) {
9096                try {
9097                    mProfileFd.close();
9098                } catch (IOException e) {
9099                }
9100                mProfileFd = null;
9101            }
9102            mProfileFd = profileFd;
9103            mProfileType = 0;
9104            mAutoStopProfiler = autoStopProfiler;
9105        }
9106    }
9107
9108    @Override
9109    public void setAlwaysFinish(boolean enabled) {
9110        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9111                "setAlwaysFinish()");
9112
9113        Settings.Global.putInt(
9114                mContext.getContentResolver(),
9115                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9116
9117        synchronized (this) {
9118            mAlwaysFinishActivities = enabled;
9119        }
9120    }
9121
9122    @Override
9123    public void setActivityController(IActivityController controller) {
9124        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9125                "setActivityController()");
9126        synchronized (this) {
9127            mController = controller;
9128            Watchdog.getInstance().setActivityController(controller);
9129        }
9130    }
9131
9132    @Override
9133    public void setUserIsMonkey(boolean userIsMonkey) {
9134        synchronized (this) {
9135            synchronized (mPidsSelfLocked) {
9136                final int callingPid = Binder.getCallingPid();
9137                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9138                if (precessRecord == null) {
9139                    throw new SecurityException("Unknown process: " + callingPid);
9140                }
9141                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9142                    throw new SecurityException("Only an instrumentation process "
9143                            + "with a UiAutomation can call setUserIsMonkey");
9144                }
9145            }
9146            mUserIsMonkey = userIsMonkey;
9147        }
9148    }
9149
9150    @Override
9151    public boolean isUserAMonkey() {
9152        synchronized (this) {
9153            // If there is a controller also implies the user is a monkey.
9154            return (mUserIsMonkey || mController != null);
9155        }
9156    }
9157
9158    public void requestBugReport() {
9159        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9160        SystemProperties.set("ctl.start", "bugreport");
9161    }
9162
9163    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9164        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9165    }
9166
9167    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9168        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9169            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9170        }
9171        return KEY_DISPATCHING_TIMEOUT;
9172    }
9173
9174    @Override
9175    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9176        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9177                != PackageManager.PERMISSION_GRANTED) {
9178            throw new SecurityException("Requires permission "
9179                    + android.Manifest.permission.FILTER_EVENTS);
9180        }
9181        ProcessRecord proc;
9182        long timeout;
9183        synchronized (this) {
9184            synchronized (mPidsSelfLocked) {
9185                proc = mPidsSelfLocked.get(pid);
9186            }
9187            timeout = getInputDispatchingTimeoutLocked(proc);
9188        }
9189
9190        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9191            return -1;
9192        }
9193
9194        return timeout;
9195    }
9196
9197    /**
9198     * Handle input dispatching timeouts.
9199     * Returns whether input dispatching should be aborted or not.
9200     */
9201    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9202            final ActivityRecord activity, final ActivityRecord parent,
9203            final boolean aboveSystem, String reason) {
9204        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9205                != PackageManager.PERMISSION_GRANTED) {
9206            throw new SecurityException("Requires permission "
9207                    + android.Manifest.permission.FILTER_EVENTS);
9208        }
9209
9210        final String annotation;
9211        if (reason == null) {
9212            annotation = "Input dispatching timed out";
9213        } else {
9214            annotation = "Input dispatching timed out (" + reason + ")";
9215        }
9216
9217        if (proc != null) {
9218            synchronized (this) {
9219                if (proc.debugging) {
9220                    return false;
9221                }
9222
9223                if (mDidDexOpt) {
9224                    // Give more time since we were dexopting.
9225                    mDidDexOpt = false;
9226                    return false;
9227                }
9228
9229                if (proc.instrumentationClass != null) {
9230                    Bundle info = new Bundle();
9231                    info.putString("shortMsg", "keyDispatchingTimedOut");
9232                    info.putString("longMsg", annotation);
9233                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9234                    return true;
9235                }
9236            }
9237            mHandler.post(new Runnable() {
9238                @Override
9239                public void run() {
9240                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9241                }
9242            });
9243        }
9244
9245        return true;
9246    }
9247
9248    public Bundle getAssistContextExtras(int requestType) {
9249        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9250                "getAssistContextExtras()");
9251        PendingAssistExtras pae;
9252        Bundle extras = new Bundle();
9253        synchronized (this) {
9254            ActivityRecord activity = getFocusedStack().mResumedActivity;
9255            if (activity == null) {
9256                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9257                return null;
9258            }
9259            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9260            if (activity.app == null || activity.app.thread == null) {
9261                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9262                return extras;
9263            }
9264            if (activity.app.pid == Binder.getCallingPid()) {
9265                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9266                return extras;
9267            }
9268            pae = new PendingAssistExtras(activity);
9269            try {
9270                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9271                        requestType);
9272                mPendingAssistExtras.add(pae);
9273                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9274            } catch (RemoteException e) {
9275                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9276                return extras;
9277            }
9278        }
9279        synchronized (pae) {
9280            while (!pae.haveResult) {
9281                try {
9282                    pae.wait();
9283                } catch (InterruptedException e) {
9284                }
9285            }
9286            if (pae.result != null) {
9287                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9288            }
9289        }
9290        synchronized (this) {
9291            mPendingAssistExtras.remove(pae);
9292            mHandler.removeCallbacks(pae);
9293        }
9294        return extras;
9295    }
9296
9297    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9298        PendingAssistExtras pae = (PendingAssistExtras)token;
9299        synchronized (pae) {
9300            pae.result = extras;
9301            pae.haveResult = true;
9302            pae.notifyAll();
9303        }
9304    }
9305
9306    public void registerProcessObserver(IProcessObserver observer) {
9307        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9308                "registerProcessObserver()");
9309        synchronized (this) {
9310            mProcessObservers.register(observer);
9311        }
9312    }
9313
9314    @Override
9315    public void unregisterProcessObserver(IProcessObserver observer) {
9316        synchronized (this) {
9317            mProcessObservers.unregister(observer);
9318        }
9319    }
9320
9321    @Override
9322    public boolean convertFromTranslucent(IBinder token) {
9323        final long origId = Binder.clearCallingIdentity();
9324        try {
9325            synchronized (this) {
9326                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9327                if (r == null) {
9328                    return false;
9329                }
9330                if (r.changeWindowTranslucency(true)) {
9331                    mWindowManager.setAppFullscreen(token, true);
9332                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9333                    return true;
9334                }
9335                return false;
9336            }
9337        } finally {
9338            Binder.restoreCallingIdentity(origId);
9339        }
9340    }
9341
9342    @Override
9343    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9344        final long origId = Binder.clearCallingIdentity();
9345        try {
9346            synchronized (this) {
9347                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9348                if (r == null) {
9349                    return false;
9350                }
9351                if (r.changeWindowTranslucency(false)) {
9352                    r.task.stack.convertToTranslucent(r, options);
9353                    mWindowManager.setAppFullscreen(token, false);
9354                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9355                    return true;
9356                }
9357                return false;
9358            }
9359        } finally {
9360            Binder.restoreCallingIdentity(origId);
9361        }
9362    }
9363
9364    @Override
9365    public ActivityOptions getActivityOptions(IBinder token) {
9366        final long origId = Binder.clearCallingIdentity();
9367        try {
9368            synchronized (this) {
9369                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9370                if (r != null) {
9371                    final ActivityOptions activityOptions = r.pendingOptions;
9372                    r.pendingOptions = null;
9373                    return activityOptions;
9374                }
9375                return null;
9376            }
9377        } finally {
9378            Binder.restoreCallingIdentity(origId);
9379        }
9380    }
9381
9382    @Override
9383    public void setImmersive(IBinder token, boolean immersive) {
9384        synchronized(this) {
9385            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9386            if (r == null) {
9387                throw new IllegalArgumentException();
9388            }
9389            r.immersive = immersive;
9390
9391            // update associated state if we're frontmost
9392            if (r == mFocusedActivity) {
9393                if (DEBUG_IMMERSIVE) {
9394                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9395                }
9396                applyUpdateLockStateLocked(r);
9397            }
9398        }
9399    }
9400
9401    @Override
9402    public boolean isImmersive(IBinder token) {
9403        synchronized (this) {
9404            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9405            if (r == null) {
9406                throw new IllegalArgumentException();
9407            }
9408            return r.immersive;
9409        }
9410    }
9411
9412    public boolean isTopActivityImmersive() {
9413        enforceNotIsolatedCaller("startActivity");
9414        synchronized (this) {
9415            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9416            return (r != null) ? r.immersive : false;
9417        }
9418    }
9419
9420    public final void enterSafeMode() {
9421        synchronized(this) {
9422            // It only makes sense to do this before the system is ready
9423            // and started launching other packages.
9424            if (!mSystemReady) {
9425                try {
9426                    AppGlobals.getPackageManager().enterSafeMode();
9427                } catch (RemoteException e) {
9428                }
9429            }
9430
9431            mSafeMode = true;
9432        }
9433    }
9434
9435    public final void showSafeModeOverlay() {
9436        View v = LayoutInflater.from(mContext).inflate(
9437                com.android.internal.R.layout.safe_mode, null);
9438        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9439        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9440        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9441        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9442        lp.gravity = Gravity.BOTTOM | Gravity.START;
9443        lp.format = v.getBackground().getOpacity();
9444        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9445                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9446        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9447        ((WindowManager)mContext.getSystemService(
9448                Context.WINDOW_SERVICE)).addView(v, lp);
9449    }
9450
9451    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9452        if (!(sender instanceof PendingIntentRecord)) {
9453            return;
9454        }
9455        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9456        synchronized (stats) {
9457            if (mBatteryStatsService.isOnBattery()) {
9458                mBatteryStatsService.enforceCallingPermission();
9459                PendingIntentRecord rec = (PendingIntentRecord)sender;
9460                int MY_UID = Binder.getCallingUid();
9461                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9462                BatteryStatsImpl.Uid.Pkg pkg =
9463                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9464                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9465                pkg.incWakeupsLocked();
9466            }
9467        }
9468    }
9469
9470    public boolean killPids(int[] pids, String pReason, boolean secure) {
9471        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9472            throw new SecurityException("killPids only available to the system");
9473        }
9474        String reason = (pReason == null) ? "Unknown" : pReason;
9475        // XXX Note: don't acquire main activity lock here, because the window
9476        // manager calls in with its locks held.
9477
9478        boolean killed = false;
9479        synchronized (mPidsSelfLocked) {
9480            int[] types = new int[pids.length];
9481            int worstType = 0;
9482            for (int i=0; i<pids.length; i++) {
9483                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9484                if (proc != null) {
9485                    int type = proc.setAdj;
9486                    types[i] = type;
9487                    if (type > worstType) {
9488                        worstType = type;
9489                    }
9490                }
9491            }
9492
9493            // If the worst oom_adj is somewhere in the cached proc LRU range,
9494            // then constrain it so we will kill all cached procs.
9495            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9496                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9497                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9498            }
9499
9500            // If this is not a secure call, don't let it kill processes that
9501            // are important.
9502            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9503                worstType = ProcessList.SERVICE_ADJ;
9504            }
9505
9506            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9507            for (int i=0; i<pids.length; i++) {
9508                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9509                if (proc == null) {
9510                    continue;
9511                }
9512                int adj = proc.setAdj;
9513                if (adj >= worstType && !proc.killedByAm) {
9514                    killUnneededProcessLocked(proc, reason);
9515                    killed = true;
9516                }
9517            }
9518        }
9519        return killed;
9520    }
9521
9522    @Override
9523    public void killUid(int uid, String reason) {
9524        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9525            throw new SecurityException("killUid only available to the system");
9526        }
9527        synchronized (this) {
9528            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9529                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9530                    reason != null ? reason : "kill uid");
9531        }
9532    }
9533
9534    @Override
9535    public boolean killProcessesBelowForeground(String reason) {
9536        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9537            throw new SecurityException("killProcessesBelowForeground() only available to system");
9538        }
9539
9540        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9541    }
9542
9543    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9544        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9545            throw new SecurityException("killProcessesBelowAdj() only available to system");
9546        }
9547
9548        boolean killed = false;
9549        synchronized (mPidsSelfLocked) {
9550            final int size = mPidsSelfLocked.size();
9551            for (int i = 0; i < size; i++) {
9552                final int pid = mPidsSelfLocked.keyAt(i);
9553                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9554                if (proc == null) continue;
9555
9556                final int adj = proc.setAdj;
9557                if (adj > belowAdj && !proc.killedByAm) {
9558                    killUnneededProcessLocked(proc, reason);
9559                    killed = true;
9560                }
9561            }
9562        }
9563        return killed;
9564    }
9565
9566    @Override
9567    public void hang(final IBinder who, boolean allowRestart) {
9568        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9569                != PackageManager.PERMISSION_GRANTED) {
9570            throw new SecurityException("Requires permission "
9571                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9572        }
9573
9574        final IBinder.DeathRecipient death = new DeathRecipient() {
9575            @Override
9576            public void binderDied() {
9577                synchronized (this) {
9578                    notifyAll();
9579                }
9580            }
9581        };
9582
9583        try {
9584            who.linkToDeath(death, 0);
9585        } catch (RemoteException e) {
9586            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9587            return;
9588        }
9589
9590        synchronized (this) {
9591            Watchdog.getInstance().setAllowRestart(allowRestart);
9592            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9593            synchronized (death) {
9594                while (who.isBinderAlive()) {
9595                    try {
9596                        death.wait();
9597                    } catch (InterruptedException e) {
9598                    }
9599                }
9600            }
9601            Watchdog.getInstance().setAllowRestart(true);
9602        }
9603    }
9604
9605    @Override
9606    public void restart() {
9607        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9608                != PackageManager.PERMISSION_GRANTED) {
9609            throw new SecurityException("Requires permission "
9610                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9611        }
9612
9613        Log.i(TAG, "Sending shutdown broadcast...");
9614
9615        BroadcastReceiver br = new BroadcastReceiver() {
9616            @Override public void onReceive(Context context, Intent intent) {
9617                // Now the broadcast is done, finish up the low-level shutdown.
9618                Log.i(TAG, "Shutting down activity manager...");
9619                shutdown(10000);
9620                Log.i(TAG, "Shutdown complete, restarting!");
9621                Process.killProcess(Process.myPid());
9622                System.exit(10);
9623            }
9624        };
9625
9626        // First send the high-level shut down broadcast.
9627        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9628        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9629        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9630        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9631        mContext.sendOrderedBroadcastAsUser(intent,
9632                UserHandle.ALL, null, br, mHandler, 0, null, null);
9633        */
9634        br.onReceive(mContext, intent);
9635    }
9636
9637    private long getLowRamTimeSinceIdle(long now) {
9638        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9639    }
9640
9641    @Override
9642    public void performIdleMaintenance() {
9643        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9644                != PackageManager.PERMISSION_GRANTED) {
9645            throw new SecurityException("Requires permission "
9646                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9647        }
9648
9649        synchronized (this) {
9650            final long now = SystemClock.uptimeMillis();
9651            final long timeSinceLastIdle = now - mLastIdleTime;
9652            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9653            mLastIdleTime = now;
9654            mLowRamTimeSinceLastIdle = 0;
9655            if (mLowRamStartTime != 0) {
9656                mLowRamStartTime = now;
9657            }
9658
9659            StringBuilder sb = new StringBuilder(128);
9660            sb.append("Idle maintenance over ");
9661            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9662            sb.append(" low RAM for ");
9663            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9664            Slog.i(TAG, sb.toString());
9665
9666            // If at least 1/3 of our time since the last idle period has been spent
9667            // with RAM low, then we want to kill processes.
9668            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9669
9670            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9671                ProcessRecord proc = mLruProcesses.get(i);
9672                if (proc.notCachedSinceIdle) {
9673                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9674                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9675                        if (doKilling && proc.initialIdlePss != 0
9676                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9677                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9678                                    + " from " + proc.initialIdlePss + ")");
9679                        }
9680                    }
9681                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9682                    proc.notCachedSinceIdle = true;
9683                    proc.initialIdlePss = 0;
9684                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9685                            isSleeping(), now);
9686                }
9687            }
9688
9689            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9690            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9691        }
9692    }
9693
9694    private void retrieveSettings() {
9695        final ContentResolver resolver = mContext.getContentResolver();
9696        String debugApp = Settings.Global.getString(
9697            resolver, Settings.Global.DEBUG_APP);
9698        boolean waitForDebugger = Settings.Global.getInt(
9699            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9700        boolean alwaysFinishActivities = Settings.Global.getInt(
9701            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9702        boolean forceRtl = Settings.Global.getInt(
9703                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9704        // Transfer any global setting for forcing RTL layout, into a System Property
9705        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9706
9707        Configuration configuration = new Configuration();
9708        Settings.System.getConfiguration(resolver, configuration);
9709        if (forceRtl) {
9710            // This will take care of setting the correct layout direction flags
9711            configuration.setLayoutDirection(configuration.locale);
9712        }
9713
9714        synchronized (this) {
9715            mDebugApp = mOrigDebugApp = debugApp;
9716            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9717            mAlwaysFinishActivities = alwaysFinishActivities;
9718            // This happens before any activities are started, so we can
9719            // change mConfiguration in-place.
9720            updateConfigurationLocked(configuration, null, false, true);
9721            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9722        }
9723    }
9724
9725    public boolean testIsSystemReady() {
9726        // no need to synchronize(this) just to read & return the value
9727        return mSystemReady;
9728    }
9729
9730    private static File getCalledPreBootReceiversFile() {
9731        File dataDir = Environment.getDataDirectory();
9732        File systemDir = new File(dataDir, "system");
9733        File fname = new File(systemDir, "called_pre_boots.dat");
9734        return fname;
9735    }
9736
9737    static final int LAST_DONE_VERSION = 10000;
9738
9739    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9740        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9741        File file = getCalledPreBootReceiversFile();
9742        FileInputStream fis = null;
9743        try {
9744            fis = new FileInputStream(file);
9745            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9746            int fvers = dis.readInt();
9747            if (fvers == LAST_DONE_VERSION) {
9748                String vers = dis.readUTF();
9749                String codename = dis.readUTF();
9750                String build = dis.readUTF();
9751                if (android.os.Build.VERSION.RELEASE.equals(vers)
9752                        && android.os.Build.VERSION.CODENAME.equals(codename)
9753                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9754                    int num = dis.readInt();
9755                    while (num > 0) {
9756                        num--;
9757                        String pkg = dis.readUTF();
9758                        String cls = dis.readUTF();
9759                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9760                    }
9761                }
9762            }
9763        } catch (FileNotFoundException e) {
9764        } catch (IOException e) {
9765            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9766        } finally {
9767            if (fis != null) {
9768                try {
9769                    fis.close();
9770                } catch (IOException e) {
9771                }
9772            }
9773        }
9774        return lastDoneReceivers;
9775    }
9776
9777    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9778        File file = getCalledPreBootReceiversFile();
9779        FileOutputStream fos = null;
9780        DataOutputStream dos = null;
9781        try {
9782            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9783            fos = new FileOutputStream(file);
9784            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9785            dos.writeInt(LAST_DONE_VERSION);
9786            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9787            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9788            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9789            dos.writeInt(list.size());
9790            for (int i=0; i<list.size(); i++) {
9791                dos.writeUTF(list.get(i).getPackageName());
9792                dos.writeUTF(list.get(i).getClassName());
9793            }
9794        } catch (IOException e) {
9795            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9796            file.delete();
9797        } finally {
9798            FileUtils.sync(fos);
9799            if (dos != null) {
9800                try {
9801                    dos.close();
9802                } catch (IOException e) {
9803                    // TODO Auto-generated catch block
9804                    e.printStackTrace();
9805                }
9806            }
9807        }
9808    }
9809
9810    public void systemReady(final Runnable goingCallback) {
9811        synchronized(this) {
9812            if (mSystemReady) {
9813                if (goingCallback != null) goingCallback.run();
9814                return;
9815            }
9816
9817            if (mRecentTasks == null) {
9818                mRecentTasks = mTaskPersister.restoreTasksLocked();
9819                if (!mRecentTasks.isEmpty()) {
9820                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
9821                }
9822                mTaskPersister.startPersisting();
9823            }
9824
9825            // Check to see if there are any update receivers to run.
9826            if (!mDidUpdate) {
9827                if (mWaitingUpdate) {
9828                    return;
9829                }
9830                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9831                List<ResolveInfo> ris = null;
9832                try {
9833                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9834                            intent, null, 0, 0);
9835                } catch (RemoteException e) {
9836                }
9837                if (ris != null) {
9838                    for (int i=ris.size()-1; i>=0; i--) {
9839                        if ((ris.get(i).activityInfo.applicationInfo.flags
9840                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9841                            ris.remove(i);
9842                        }
9843                    }
9844                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9845
9846                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9847
9848                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9849                    for (int i=0; i<ris.size(); i++) {
9850                        ActivityInfo ai = ris.get(i).activityInfo;
9851                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9852                        if (lastDoneReceivers.contains(comp)) {
9853                            // We already did the pre boot receiver for this app with the current
9854                            // platform version, so don't do it again...
9855                            ris.remove(i);
9856                            i--;
9857                            // ...however, do keep it as one that has been done, so we don't
9858                            // forget about it when rewriting the file of last done receivers.
9859                            doneReceivers.add(comp);
9860                        }
9861                    }
9862
9863                    final int[] users = getUsersLocked();
9864                    for (int i=0; i<ris.size(); i++) {
9865                        ActivityInfo ai = ris.get(i).activityInfo;
9866                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9867                        doneReceivers.add(comp);
9868                        intent.setComponent(comp);
9869                        for (int j=0; j<users.length; j++) {
9870                            IIntentReceiver finisher = null;
9871                            if (i == ris.size()-1 && j == users.length-1) {
9872                                finisher = new IIntentReceiver.Stub() {
9873                                    public void performReceive(Intent intent, int resultCode,
9874                                            String data, Bundle extras, boolean ordered,
9875                                            boolean sticky, int sendingUser) {
9876                                        // The raw IIntentReceiver interface is called
9877                                        // with the AM lock held, so redispatch to
9878                                        // execute our code without the lock.
9879                                        mHandler.post(new Runnable() {
9880                                            public void run() {
9881                                                synchronized (ActivityManagerService.this) {
9882                                                    mDidUpdate = true;
9883                                                }
9884                                                writeLastDonePreBootReceivers(doneReceivers);
9885                                                showBootMessage(mContext.getText(
9886                                                        R.string.android_upgrading_complete),
9887                                                        false);
9888                                                systemReady(goingCallback);
9889                                            }
9890                                        });
9891                                    }
9892                                };
9893                            }
9894                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9895                                    + " for user " + users[j]);
9896                            broadcastIntentLocked(null, null, intent, null, finisher,
9897                                    0, null, null, null, AppOpsManager.OP_NONE,
9898                                    true, false, MY_PID, Process.SYSTEM_UID,
9899                                    users[j]);
9900                            if (finisher != null) {
9901                                mWaitingUpdate = true;
9902                            }
9903                        }
9904                    }
9905                }
9906                if (mWaitingUpdate) {
9907                    return;
9908                }
9909                mDidUpdate = true;
9910            }
9911
9912            mAppOpsService.systemReady();
9913            mUsageStatsService.systemReady();
9914            mSystemReady = true;
9915        }
9916
9917        ArrayList<ProcessRecord> procsToKill = null;
9918        synchronized(mPidsSelfLocked) {
9919            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9920                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9921                if (!isAllowedWhileBooting(proc.info)){
9922                    if (procsToKill == null) {
9923                        procsToKill = new ArrayList<ProcessRecord>();
9924                    }
9925                    procsToKill.add(proc);
9926                }
9927            }
9928        }
9929
9930        synchronized(this) {
9931            if (procsToKill != null) {
9932                for (int i=procsToKill.size()-1; i>=0; i--) {
9933                    ProcessRecord proc = procsToKill.get(i);
9934                    Slog.i(TAG, "Removing system update proc: " + proc);
9935                    removeProcessLocked(proc, true, false, "system update done");
9936                }
9937            }
9938
9939            // Now that we have cleaned up any update processes, we
9940            // are ready to start launching real processes and know that
9941            // we won't trample on them any more.
9942            mProcessesReady = true;
9943        }
9944
9945        Slog.i(TAG, "System now ready");
9946        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9947            SystemClock.uptimeMillis());
9948
9949        synchronized(this) {
9950            // Make sure we have no pre-ready processes sitting around.
9951
9952            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9953                ResolveInfo ri = mContext.getPackageManager()
9954                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9955                                STOCK_PM_FLAGS);
9956                CharSequence errorMsg = null;
9957                if (ri != null) {
9958                    ActivityInfo ai = ri.activityInfo;
9959                    ApplicationInfo app = ai.applicationInfo;
9960                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9961                        mTopAction = Intent.ACTION_FACTORY_TEST;
9962                        mTopData = null;
9963                        mTopComponent = new ComponentName(app.packageName,
9964                                ai.name);
9965                    } else {
9966                        errorMsg = mContext.getResources().getText(
9967                                com.android.internal.R.string.factorytest_not_system);
9968                    }
9969                } else {
9970                    errorMsg = mContext.getResources().getText(
9971                            com.android.internal.R.string.factorytest_no_action);
9972                }
9973                if (errorMsg != null) {
9974                    mTopAction = null;
9975                    mTopData = null;
9976                    mTopComponent = null;
9977                    Message msg = Message.obtain();
9978                    msg.what = SHOW_FACTORY_ERROR_MSG;
9979                    msg.getData().putCharSequence("msg", errorMsg);
9980                    mHandler.sendMessage(msg);
9981                }
9982            }
9983        }
9984
9985        retrieveSettings();
9986
9987        synchronized (this) {
9988            readGrantedUriPermissionsLocked();
9989        }
9990
9991        if (goingCallback != null) goingCallback.run();
9992
9993        mSystemServiceManager.startUser(mCurrentUserId);
9994
9995        synchronized (this) {
9996            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9997                try {
9998                    List apps = AppGlobals.getPackageManager().
9999                        getPersistentApplications(STOCK_PM_FLAGS);
10000                    if (apps != null) {
10001                        int N = apps.size();
10002                        int i;
10003                        for (i=0; i<N; i++) {
10004                            ApplicationInfo info
10005                                = (ApplicationInfo)apps.get(i);
10006                            if (info != null &&
10007                                    !info.packageName.equals("android")) {
10008                                addAppLocked(info, false, null /* ABI override */);
10009                            }
10010                        }
10011                    }
10012                } catch (RemoteException ex) {
10013                    // pm is in same process, this will never happen.
10014                }
10015            }
10016
10017            // Start up initial activity.
10018            mBooting = true;
10019
10020            try {
10021                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10022                    Message msg = Message.obtain();
10023                    msg.what = SHOW_UID_ERROR_MSG;
10024                    mHandler.sendMessage(msg);
10025                }
10026            } catch (RemoteException e) {
10027            }
10028
10029            long ident = Binder.clearCallingIdentity();
10030            try {
10031                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10032                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10033                        | Intent.FLAG_RECEIVER_FOREGROUND);
10034                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10035                broadcastIntentLocked(null, null, intent,
10036                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10037                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10038                intent = new Intent(Intent.ACTION_USER_STARTING);
10039                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10040                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10041                broadcastIntentLocked(null, null, intent,
10042                        null, new IIntentReceiver.Stub() {
10043                            @Override
10044                            public void performReceive(Intent intent, int resultCode, String data,
10045                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10046                                    throws RemoteException {
10047                            }
10048                        }, 0, null, null,
10049                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10050                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10051            } catch (Throwable t) {
10052                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10053            } finally {
10054                Binder.restoreCallingIdentity(ident);
10055            }
10056            mStackSupervisor.resumeTopActivitiesLocked();
10057            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10058        }
10059    }
10060
10061    private boolean makeAppCrashingLocked(ProcessRecord app,
10062            String shortMsg, String longMsg, String stackTrace) {
10063        app.crashing = true;
10064        app.crashingReport = generateProcessError(app,
10065                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10066        startAppProblemLocked(app);
10067        app.stopFreezingAllLocked();
10068        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10069    }
10070
10071    private void makeAppNotRespondingLocked(ProcessRecord app,
10072            String activity, String shortMsg, String longMsg) {
10073        app.notResponding = true;
10074        app.notRespondingReport = generateProcessError(app,
10075                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10076                activity, shortMsg, longMsg, null);
10077        startAppProblemLocked(app);
10078        app.stopFreezingAllLocked();
10079    }
10080
10081    /**
10082     * Generate a process error record, suitable for attachment to a ProcessRecord.
10083     *
10084     * @param app The ProcessRecord in which the error occurred.
10085     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10086     *                      ActivityManager.AppErrorStateInfo
10087     * @param activity The activity associated with the crash, if known.
10088     * @param shortMsg Short message describing the crash.
10089     * @param longMsg Long message describing the crash.
10090     * @param stackTrace Full crash stack trace, may be null.
10091     *
10092     * @return Returns a fully-formed AppErrorStateInfo record.
10093     */
10094    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10095            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10096        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10097
10098        report.condition = condition;
10099        report.processName = app.processName;
10100        report.pid = app.pid;
10101        report.uid = app.info.uid;
10102        report.tag = activity;
10103        report.shortMsg = shortMsg;
10104        report.longMsg = longMsg;
10105        report.stackTrace = stackTrace;
10106
10107        return report;
10108    }
10109
10110    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10111        synchronized (this) {
10112            app.crashing = false;
10113            app.crashingReport = null;
10114            app.notResponding = false;
10115            app.notRespondingReport = null;
10116            if (app.anrDialog == fromDialog) {
10117                app.anrDialog = null;
10118            }
10119            if (app.waitDialog == fromDialog) {
10120                app.waitDialog = null;
10121            }
10122            if (app.pid > 0 && app.pid != MY_PID) {
10123                handleAppCrashLocked(app, null, null, null);
10124                killUnneededProcessLocked(app, "user request after error");
10125            }
10126        }
10127    }
10128
10129    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10130            String stackTrace) {
10131        long now = SystemClock.uptimeMillis();
10132
10133        Long crashTime;
10134        if (!app.isolated) {
10135            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10136        } else {
10137            crashTime = null;
10138        }
10139        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10140            // This process loses!
10141            Slog.w(TAG, "Process " + app.info.processName
10142                    + " has crashed too many times: killing!");
10143            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10144                    app.userId, app.info.processName, app.uid);
10145            mStackSupervisor.handleAppCrashLocked(app);
10146            if (!app.persistent) {
10147                // We don't want to start this process again until the user
10148                // explicitly does so...  but for persistent process, we really
10149                // need to keep it running.  If a persistent process is actually
10150                // repeatedly crashing, then badness for everyone.
10151                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10152                        app.info.processName);
10153                if (!app.isolated) {
10154                    // XXX We don't have a way to mark isolated processes
10155                    // as bad, since they don't have a peristent identity.
10156                    mBadProcesses.put(app.info.processName, app.uid,
10157                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10158                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10159                }
10160                app.bad = true;
10161                app.removed = true;
10162                // Don't let services in this process be restarted and potentially
10163                // annoy the user repeatedly.  Unless it is persistent, since those
10164                // processes run critical code.
10165                removeProcessLocked(app, false, false, "crash");
10166                mStackSupervisor.resumeTopActivitiesLocked();
10167                return false;
10168            }
10169            mStackSupervisor.resumeTopActivitiesLocked();
10170        } else {
10171            mStackSupervisor.finishTopRunningActivityLocked(app);
10172        }
10173
10174        // Bump up the crash count of any services currently running in the proc.
10175        for (int i=app.services.size()-1; i>=0; i--) {
10176            // Any services running in the application need to be placed
10177            // back in the pending list.
10178            ServiceRecord sr = app.services.valueAt(i);
10179            sr.crashCount++;
10180        }
10181
10182        // If the crashing process is what we consider to be the "home process" and it has been
10183        // replaced by a third-party app, clear the package preferred activities from packages
10184        // with a home activity running in the process to prevent a repeatedly crashing app
10185        // from blocking the user to manually clear the list.
10186        final ArrayList<ActivityRecord> activities = app.activities;
10187        if (app == mHomeProcess && activities.size() > 0
10188                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10189            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10190                final ActivityRecord r = activities.get(activityNdx);
10191                if (r.isHomeActivity()) {
10192                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10193                    try {
10194                        ActivityThread.getPackageManager()
10195                                .clearPackagePreferredActivities(r.packageName);
10196                    } catch (RemoteException c) {
10197                        // pm is in same process, this will never happen.
10198                    }
10199                }
10200            }
10201        }
10202
10203        if (!app.isolated) {
10204            // XXX Can't keep track of crash times for isolated processes,
10205            // because they don't have a perisistent identity.
10206            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10207        }
10208
10209        return true;
10210    }
10211
10212    void startAppProblemLocked(ProcessRecord app) {
10213        if (app.userId == mCurrentUserId) {
10214            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10215                    mContext, app.info.packageName, app.info.flags);
10216        } else {
10217            // If this app is not running under the current user, then we
10218            // can't give it a report button because that would require
10219            // launching the report UI under a different user.
10220            app.errorReportReceiver = null;
10221        }
10222        skipCurrentReceiverLocked(app);
10223    }
10224
10225    void skipCurrentReceiverLocked(ProcessRecord app) {
10226        for (BroadcastQueue queue : mBroadcastQueues) {
10227            queue.skipCurrentReceiverLocked(app);
10228        }
10229    }
10230
10231    /**
10232     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10233     * The application process will exit immediately after this call returns.
10234     * @param app object of the crashing app, null for the system server
10235     * @param crashInfo describing the exception
10236     */
10237    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10238        ProcessRecord r = findAppProcess(app, "Crash");
10239        final String processName = app == null ? "system_server"
10240                : (r == null ? "unknown" : r.processName);
10241
10242        handleApplicationCrashInner("crash", r, processName, crashInfo);
10243    }
10244
10245    /* Native crash reporting uses this inner version because it needs to be somewhat
10246     * decoupled from the AM-managed cleanup lifecycle
10247     */
10248    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10249            ApplicationErrorReport.CrashInfo crashInfo) {
10250        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10251                UserHandle.getUserId(Binder.getCallingUid()), processName,
10252                r == null ? -1 : r.info.flags,
10253                crashInfo.exceptionClassName,
10254                crashInfo.exceptionMessage,
10255                crashInfo.throwFileName,
10256                crashInfo.throwLineNumber);
10257
10258        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10259
10260        crashApplication(r, crashInfo);
10261    }
10262
10263    public void handleApplicationStrictModeViolation(
10264            IBinder app,
10265            int violationMask,
10266            StrictMode.ViolationInfo info) {
10267        ProcessRecord r = findAppProcess(app, "StrictMode");
10268        if (r == null) {
10269            return;
10270        }
10271
10272        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10273            Integer stackFingerprint = info.hashCode();
10274            boolean logIt = true;
10275            synchronized (mAlreadyLoggedViolatedStacks) {
10276                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10277                    logIt = false;
10278                    // TODO: sub-sample into EventLog for these, with
10279                    // the info.durationMillis?  Then we'd get
10280                    // the relative pain numbers, without logging all
10281                    // the stack traces repeatedly.  We'd want to do
10282                    // likewise in the client code, which also does
10283                    // dup suppression, before the Binder call.
10284                } else {
10285                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10286                        mAlreadyLoggedViolatedStacks.clear();
10287                    }
10288                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10289                }
10290            }
10291            if (logIt) {
10292                logStrictModeViolationToDropBox(r, info);
10293            }
10294        }
10295
10296        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10297            AppErrorResult result = new AppErrorResult();
10298            synchronized (this) {
10299                final long origId = Binder.clearCallingIdentity();
10300
10301                Message msg = Message.obtain();
10302                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10303                HashMap<String, Object> data = new HashMap<String, Object>();
10304                data.put("result", result);
10305                data.put("app", r);
10306                data.put("violationMask", violationMask);
10307                data.put("info", info);
10308                msg.obj = data;
10309                mHandler.sendMessage(msg);
10310
10311                Binder.restoreCallingIdentity(origId);
10312            }
10313            int res = result.get();
10314            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10315        }
10316    }
10317
10318    // Depending on the policy in effect, there could be a bunch of
10319    // these in quick succession so we try to batch these together to
10320    // minimize disk writes, number of dropbox entries, and maximize
10321    // compression, by having more fewer, larger records.
10322    private void logStrictModeViolationToDropBox(
10323            ProcessRecord process,
10324            StrictMode.ViolationInfo info) {
10325        if (info == null) {
10326            return;
10327        }
10328        final boolean isSystemApp = process == null ||
10329                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10330                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10331        final String processName = process == null ? "unknown" : process.processName;
10332        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10333        final DropBoxManager dbox = (DropBoxManager)
10334                mContext.getSystemService(Context.DROPBOX_SERVICE);
10335
10336        // Exit early if the dropbox isn't configured to accept this report type.
10337        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10338
10339        boolean bufferWasEmpty;
10340        boolean needsFlush;
10341        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10342        synchronized (sb) {
10343            bufferWasEmpty = sb.length() == 0;
10344            appendDropBoxProcessHeaders(process, processName, sb);
10345            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10346            sb.append("System-App: ").append(isSystemApp).append("\n");
10347            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10348            if (info.violationNumThisLoop != 0) {
10349                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10350            }
10351            if (info.numAnimationsRunning != 0) {
10352                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10353            }
10354            if (info.broadcastIntentAction != null) {
10355                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10356            }
10357            if (info.durationMillis != -1) {
10358                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10359            }
10360            if (info.numInstances != -1) {
10361                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10362            }
10363            if (info.tags != null) {
10364                for (String tag : info.tags) {
10365                    sb.append("Span-Tag: ").append(tag).append("\n");
10366                }
10367            }
10368            sb.append("\n");
10369            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10370                sb.append(info.crashInfo.stackTrace);
10371            }
10372            sb.append("\n");
10373
10374            // Only buffer up to ~64k.  Various logging bits truncate
10375            // things at 128k.
10376            needsFlush = (sb.length() > 64 * 1024);
10377        }
10378
10379        // Flush immediately if the buffer's grown too large, or this
10380        // is a non-system app.  Non-system apps are isolated with a
10381        // different tag & policy and not batched.
10382        //
10383        // Batching is useful during internal testing with
10384        // StrictMode settings turned up high.  Without batching,
10385        // thousands of separate files could be created on boot.
10386        if (!isSystemApp || needsFlush) {
10387            new Thread("Error dump: " + dropboxTag) {
10388                @Override
10389                public void run() {
10390                    String report;
10391                    synchronized (sb) {
10392                        report = sb.toString();
10393                        sb.delete(0, sb.length());
10394                        sb.trimToSize();
10395                    }
10396                    if (report.length() != 0) {
10397                        dbox.addText(dropboxTag, report);
10398                    }
10399                }
10400            }.start();
10401            return;
10402        }
10403
10404        // System app batching:
10405        if (!bufferWasEmpty) {
10406            // An existing dropbox-writing thread is outstanding, so
10407            // we don't need to start it up.  The existing thread will
10408            // catch the buffer appends we just did.
10409            return;
10410        }
10411
10412        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10413        // (After this point, we shouldn't access AMS internal data structures.)
10414        new Thread("Error dump: " + dropboxTag) {
10415            @Override
10416            public void run() {
10417                // 5 second sleep to let stacks arrive and be batched together
10418                try {
10419                    Thread.sleep(5000);  // 5 seconds
10420                } catch (InterruptedException e) {}
10421
10422                String errorReport;
10423                synchronized (mStrictModeBuffer) {
10424                    errorReport = mStrictModeBuffer.toString();
10425                    if (errorReport.length() == 0) {
10426                        return;
10427                    }
10428                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10429                    mStrictModeBuffer.trimToSize();
10430                }
10431                dbox.addText(dropboxTag, errorReport);
10432            }
10433        }.start();
10434    }
10435
10436    /**
10437     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10438     * @param app object of the crashing app, null for the system server
10439     * @param tag reported by the caller
10440     * @param crashInfo describing the context of the error
10441     * @return true if the process should exit immediately (WTF is fatal)
10442     */
10443    public boolean handleApplicationWtf(IBinder app, String tag,
10444            ApplicationErrorReport.CrashInfo crashInfo) {
10445        ProcessRecord r = findAppProcess(app, "WTF");
10446        final String processName = app == null ? "system_server"
10447                : (r == null ? "unknown" : r.processName);
10448
10449        EventLog.writeEvent(EventLogTags.AM_WTF,
10450                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10451                processName,
10452                r == null ? -1 : r.info.flags,
10453                tag, crashInfo.exceptionMessage);
10454
10455        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10456
10457        if (r != null && r.pid != Process.myPid() &&
10458                Settings.Global.getInt(mContext.getContentResolver(),
10459                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10460            crashApplication(r, crashInfo);
10461            return true;
10462        } else {
10463            return false;
10464        }
10465    }
10466
10467    /**
10468     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10469     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10470     */
10471    private ProcessRecord findAppProcess(IBinder app, String reason) {
10472        if (app == null) {
10473            return null;
10474        }
10475
10476        synchronized (this) {
10477            final int NP = mProcessNames.getMap().size();
10478            for (int ip=0; ip<NP; ip++) {
10479                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10480                final int NA = apps.size();
10481                for (int ia=0; ia<NA; ia++) {
10482                    ProcessRecord p = apps.valueAt(ia);
10483                    if (p.thread != null && p.thread.asBinder() == app) {
10484                        return p;
10485                    }
10486                }
10487            }
10488
10489            Slog.w(TAG, "Can't find mystery application for " + reason
10490                    + " from pid=" + Binder.getCallingPid()
10491                    + " uid=" + Binder.getCallingUid() + ": " + app);
10492            return null;
10493        }
10494    }
10495
10496    /**
10497     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10498     * to append various headers to the dropbox log text.
10499     */
10500    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10501            StringBuilder sb) {
10502        // Watchdog thread ends up invoking this function (with
10503        // a null ProcessRecord) to add the stack file to dropbox.
10504        // Do not acquire a lock on this (am) in such cases, as it
10505        // could cause a potential deadlock, if and when watchdog
10506        // is invoked due to unavailability of lock on am and it
10507        // would prevent watchdog from killing system_server.
10508        if (process == null) {
10509            sb.append("Process: ").append(processName).append("\n");
10510            return;
10511        }
10512        // Note: ProcessRecord 'process' is guarded by the service
10513        // instance.  (notably process.pkgList, which could otherwise change
10514        // concurrently during execution of this method)
10515        synchronized (this) {
10516            sb.append("Process: ").append(processName).append("\n");
10517            int flags = process.info.flags;
10518            IPackageManager pm = AppGlobals.getPackageManager();
10519            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10520            for (int ip=0; ip<process.pkgList.size(); ip++) {
10521                String pkg = process.pkgList.keyAt(ip);
10522                sb.append("Package: ").append(pkg);
10523                try {
10524                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10525                    if (pi != null) {
10526                        sb.append(" v").append(pi.versionCode);
10527                        if (pi.versionName != null) {
10528                            sb.append(" (").append(pi.versionName).append(")");
10529                        }
10530                    }
10531                } catch (RemoteException e) {
10532                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10533                }
10534                sb.append("\n");
10535            }
10536        }
10537    }
10538
10539    private static String processClass(ProcessRecord process) {
10540        if (process == null || process.pid == MY_PID) {
10541            return "system_server";
10542        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10543            return "system_app";
10544        } else {
10545            return "data_app";
10546        }
10547    }
10548
10549    /**
10550     * Write a description of an error (crash, WTF, ANR) to the drop box.
10551     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10552     * @param process which caused the error, null means the system server
10553     * @param activity which triggered the error, null if unknown
10554     * @param parent activity related to the error, null if unknown
10555     * @param subject line related to the error, null if absent
10556     * @param report in long form describing the error, null if absent
10557     * @param logFile to include in the report, null if none
10558     * @param crashInfo giving an application stack trace, null if absent
10559     */
10560    public void addErrorToDropBox(String eventType,
10561            ProcessRecord process, String processName, ActivityRecord activity,
10562            ActivityRecord parent, String subject,
10563            final String report, final File logFile,
10564            final ApplicationErrorReport.CrashInfo crashInfo) {
10565        // NOTE -- this must never acquire the ActivityManagerService lock,
10566        // otherwise the watchdog may be prevented from resetting the system.
10567
10568        final String dropboxTag = processClass(process) + "_" + eventType;
10569        final DropBoxManager dbox = (DropBoxManager)
10570                mContext.getSystemService(Context.DROPBOX_SERVICE);
10571
10572        // Exit early if the dropbox isn't configured to accept this report type.
10573        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10574
10575        final StringBuilder sb = new StringBuilder(1024);
10576        appendDropBoxProcessHeaders(process, processName, sb);
10577        if (activity != null) {
10578            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10579        }
10580        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10581            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10582        }
10583        if (parent != null && parent != activity) {
10584            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10585        }
10586        if (subject != null) {
10587            sb.append("Subject: ").append(subject).append("\n");
10588        }
10589        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10590        if (Debug.isDebuggerConnected()) {
10591            sb.append("Debugger: Connected\n");
10592        }
10593        sb.append("\n");
10594
10595        // Do the rest in a worker thread to avoid blocking the caller on I/O
10596        // (After this point, we shouldn't access AMS internal data structures.)
10597        Thread worker = new Thread("Error dump: " + dropboxTag) {
10598            @Override
10599            public void run() {
10600                if (report != null) {
10601                    sb.append(report);
10602                }
10603                if (logFile != null) {
10604                    try {
10605                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10606                                    "\n\n[[TRUNCATED]]"));
10607                    } catch (IOException e) {
10608                        Slog.e(TAG, "Error reading " + logFile, e);
10609                    }
10610                }
10611                if (crashInfo != null && crashInfo.stackTrace != null) {
10612                    sb.append(crashInfo.stackTrace);
10613                }
10614
10615                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10616                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10617                if (lines > 0) {
10618                    sb.append("\n");
10619
10620                    // Merge several logcat streams, and take the last N lines
10621                    InputStreamReader input = null;
10622                    try {
10623                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10624                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10625                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10626
10627                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10628                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10629                        input = new InputStreamReader(logcat.getInputStream());
10630
10631                        int num;
10632                        char[] buf = new char[8192];
10633                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10634                    } catch (IOException e) {
10635                        Slog.e(TAG, "Error running logcat", e);
10636                    } finally {
10637                        if (input != null) try { input.close(); } catch (IOException e) {}
10638                    }
10639                }
10640
10641                dbox.addText(dropboxTag, sb.toString());
10642            }
10643        };
10644
10645        if (process == null) {
10646            // If process is null, we are being called from some internal code
10647            // and may be about to die -- run this synchronously.
10648            worker.run();
10649        } else {
10650            worker.start();
10651        }
10652    }
10653
10654    /**
10655     * Bring up the "unexpected error" dialog box for a crashing app.
10656     * Deal with edge cases (intercepts from instrumented applications,
10657     * ActivityController, error intent receivers, that sort of thing).
10658     * @param r the application crashing
10659     * @param crashInfo describing the failure
10660     */
10661    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10662        long timeMillis = System.currentTimeMillis();
10663        String shortMsg = crashInfo.exceptionClassName;
10664        String longMsg = crashInfo.exceptionMessage;
10665        String stackTrace = crashInfo.stackTrace;
10666        if (shortMsg != null && longMsg != null) {
10667            longMsg = shortMsg + ": " + longMsg;
10668        } else if (shortMsg != null) {
10669            longMsg = shortMsg;
10670        }
10671
10672        AppErrorResult result = new AppErrorResult();
10673        synchronized (this) {
10674            if (mController != null) {
10675                try {
10676                    String name = r != null ? r.processName : null;
10677                    int pid = r != null ? r.pid : Binder.getCallingPid();
10678                    if (!mController.appCrashed(name, pid,
10679                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10680                        Slog.w(TAG, "Force-killing crashed app " + name
10681                                + " at watcher's request");
10682                        Process.killProcess(pid);
10683                        return;
10684                    }
10685                } catch (RemoteException e) {
10686                    mController = null;
10687                    Watchdog.getInstance().setActivityController(null);
10688                }
10689            }
10690
10691            final long origId = Binder.clearCallingIdentity();
10692
10693            // If this process is running instrumentation, finish it.
10694            if (r != null && r.instrumentationClass != null) {
10695                Slog.w(TAG, "Error in app " + r.processName
10696                      + " running instrumentation " + r.instrumentationClass + ":");
10697                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10698                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10699                Bundle info = new Bundle();
10700                info.putString("shortMsg", shortMsg);
10701                info.putString("longMsg", longMsg);
10702                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10703                Binder.restoreCallingIdentity(origId);
10704                return;
10705            }
10706
10707            // If we can't identify the process or it's already exceeded its crash quota,
10708            // quit right away without showing a crash dialog.
10709            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10710                Binder.restoreCallingIdentity(origId);
10711                return;
10712            }
10713
10714            Message msg = Message.obtain();
10715            msg.what = SHOW_ERROR_MSG;
10716            HashMap data = new HashMap();
10717            data.put("result", result);
10718            data.put("app", r);
10719            msg.obj = data;
10720            mHandler.sendMessage(msg);
10721
10722            Binder.restoreCallingIdentity(origId);
10723        }
10724
10725        int res = result.get();
10726
10727        Intent appErrorIntent = null;
10728        synchronized (this) {
10729            if (r != null && !r.isolated) {
10730                // XXX Can't keep track of crash time for isolated processes,
10731                // since they don't have a persistent identity.
10732                mProcessCrashTimes.put(r.info.processName, r.uid,
10733                        SystemClock.uptimeMillis());
10734            }
10735            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10736                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10737            }
10738        }
10739
10740        if (appErrorIntent != null) {
10741            try {
10742                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10743            } catch (ActivityNotFoundException e) {
10744                Slog.w(TAG, "bug report receiver dissappeared", e);
10745            }
10746        }
10747    }
10748
10749    Intent createAppErrorIntentLocked(ProcessRecord r,
10750            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10751        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10752        if (report == null) {
10753            return null;
10754        }
10755        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10756        result.setComponent(r.errorReportReceiver);
10757        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10758        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10759        return result;
10760    }
10761
10762    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10763            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10764        if (r.errorReportReceiver == null) {
10765            return null;
10766        }
10767
10768        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10769            return null;
10770        }
10771
10772        ApplicationErrorReport report = new ApplicationErrorReport();
10773        report.packageName = r.info.packageName;
10774        report.installerPackageName = r.errorReportReceiver.getPackageName();
10775        report.processName = r.processName;
10776        report.time = timeMillis;
10777        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10778
10779        if (r.crashing || r.forceCrashReport) {
10780            report.type = ApplicationErrorReport.TYPE_CRASH;
10781            report.crashInfo = crashInfo;
10782        } else if (r.notResponding) {
10783            report.type = ApplicationErrorReport.TYPE_ANR;
10784            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10785
10786            report.anrInfo.activity = r.notRespondingReport.tag;
10787            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10788            report.anrInfo.info = r.notRespondingReport.longMsg;
10789        }
10790
10791        return report;
10792    }
10793
10794    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10795        enforceNotIsolatedCaller("getProcessesInErrorState");
10796        // assume our apps are happy - lazy create the list
10797        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10798
10799        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10800                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10801        int userId = UserHandle.getUserId(Binder.getCallingUid());
10802
10803        synchronized (this) {
10804
10805            // iterate across all processes
10806            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10807                ProcessRecord app = mLruProcesses.get(i);
10808                if (!allUsers && app.userId != userId) {
10809                    continue;
10810                }
10811                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10812                    // This one's in trouble, so we'll generate a report for it
10813                    // crashes are higher priority (in case there's a crash *and* an anr)
10814                    ActivityManager.ProcessErrorStateInfo report = null;
10815                    if (app.crashing) {
10816                        report = app.crashingReport;
10817                    } else if (app.notResponding) {
10818                        report = app.notRespondingReport;
10819                    }
10820
10821                    if (report != null) {
10822                        if (errList == null) {
10823                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10824                        }
10825                        errList.add(report);
10826                    } else {
10827                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10828                                " crashing = " + app.crashing +
10829                                " notResponding = " + app.notResponding);
10830                    }
10831                }
10832            }
10833        }
10834
10835        return errList;
10836    }
10837
10838    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10839        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10840            if (currApp != null) {
10841                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10842            }
10843            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10844        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10845            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10846        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10847            if (currApp != null) {
10848                currApp.lru = 0;
10849            }
10850            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10851        } else if (adj >= ProcessList.SERVICE_ADJ) {
10852            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10853        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10854            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10855        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10856            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10857        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10858            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10859        } else {
10860            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10861        }
10862    }
10863
10864    private void fillInProcMemInfo(ProcessRecord app,
10865            ActivityManager.RunningAppProcessInfo outInfo) {
10866        outInfo.pid = app.pid;
10867        outInfo.uid = app.info.uid;
10868        if (mHeavyWeightProcess == app) {
10869            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10870        }
10871        if (app.persistent) {
10872            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10873        }
10874        if (app.activities.size() > 0) {
10875            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10876        }
10877        outInfo.lastTrimLevel = app.trimMemoryLevel;
10878        int adj = app.curAdj;
10879        outInfo.importance = oomAdjToImportance(adj, outInfo);
10880        outInfo.importanceReasonCode = app.adjTypeCode;
10881        outInfo.processState = app.curProcState;
10882    }
10883
10884    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10885        enforceNotIsolatedCaller("getRunningAppProcesses");
10886        // Lazy instantiation of list
10887        List<ActivityManager.RunningAppProcessInfo> runList = null;
10888        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10889                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10890        int userId = UserHandle.getUserId(Binder.getCallingUid());
10891        synchronized (this) {
10892            // Iterate across all processes
10893            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10894                ProcessRecord app = mLruProcesses.get(i);
10895                if (!allUsers && app.userId != userId) {
10896                    continue;
10897                }
10898                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10899                    // Generate process state info for running application
10900                    ActivityManager.RunningAppProcessInfo currApp =
10901                        new ActivityManager.RunningAppProcessInfo(app.processName,
10902                                app.pid, app.getPackageList());
10903                    fillInProcMemInfo(app, currApp);
10904                    if (app.adjSource instanceof ProcessRecord) {
10905                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10906                        currApp.importanceReasonImportance = oomAdjToImportance(
10907                                app.adjSourceOom, null);
10908                    } else if (app.adjSource instanceof ActivityRecord) {
10909                        ActivityRecord r = (ActivityRecord)app.adjSource;
10910                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10911                    }
10912                    if (app.adjTarget instanceof ComponentName) {
10913                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10914                    }
10915                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10916                    //        + " lru=" + currApp.lru);
10917                    if (runList == null) {
10918                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10919                    }
10920                    runList.add(currApp);
10921                }
10922            }
10923        }
10924        return runList;
10925    }
10926
10927    public List<ApplicationInfo> getRunningExternalApplications() {
10928        enforceNotIsolatedCaller("getRunningExternalApplications");
10929        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10930        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10931        if (runningApps != null && runningApps.size() > 0) {
10932            Set<String> extList = new HashSet<String>();
10933            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10934                if (app.pkgList != null) {
10935                    for (String pkg : app.pkgList) {
10936                        extList.add(pkg);
10937                    }
10938                }
10939            }
10940            IPackageManager pm = AppGlobals.getPackageManager();
10941            for (String pkg : extList) {
10942                try {
10943                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10944                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10945                        retList.add(info);
10946                    }
10947                } catch (RemoteException e) {
10948                }
10949            }
10950        }
10951        return retList;
10952    }
10953
10954    @Override
10955    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10956        enforceNotIsolatedCaller("getMyMemoryState");
10957        synchronized (this) {
10958            ProcessRecord proc;
10959            synchronized (mPidsSelfLocked) {
10960                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10961            }
10962            fillInProcMemInfo(proc, outInfo);
10963        }
10964    }
10965
10966    @Override
10967    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10968        if (checkCallingPermission(android.Manifest.permission.DUMP)
10969                != PackageManager.PERMISSION_GRANTED) {
10970            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10971                    + Binder.getCallingPid()
10972                    + ", uid=" + Binder.getCallingUid()
10973                    + " without permission "
10974                    + android.Manifest.permission.DUMP);
10975            return;
10976        }
10977
10978        boolean dumpAll = false;
10979        boolean dumpClient = false;
10980        String dumpPackage = null;
10981
10982        int opti = 0;
10983        while (opti < args.length) {
10984            String opt = args[opti];
10985            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10986                break;
10987            }
10988            opti++;
10989            if ("-a".equals(opt)) {
10990                dumpAll = true;
10991            } else if ("-c".equals(opt)) {
10992                dumpClient = true;
10993            } else if ("-h".equals(opt)) {
10994                pw.println("Activity manager dump options:");
10995                pw.println("  [-a] [-c] [-h] [cmd] ...");
10996                pw.println("  cmd may be one of:");
10997                pw.println("    a[ctivities]: activity stack state");
10998                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
10999                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11000                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11001                pw.println("    o[om]: out of memory management");
11002                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11003                pw.println("    provider [COMP_SPEC]: provider client-side state");
11004                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11005                pw.println("    service [COMP_SPEC]: service client-side state");
11006                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11007                pw.println("    all: dump all activities");
11008                pw.println("    top: dump the top activity");
11009                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11010                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11011                pw.println("    a partial substring in a component name, a");
11012                pw.println("    hex object identifier.");
11013                pw.println("  -a: include all available server state.");
11014                pw.println("  -c: include client state.");
11015                return;
11016            } else {
11017                pw.println("Unknown argument: " + opt + "; use -h for help");
11018            }
11019        }
11020
11021        long origId = Binder.clearCallingIdentity();
11022        boolean more = false;
11023        // Is the caller requesting to dump a particular piece of data?
11024        if (opti < args.length) {
11025            String cmd = args[opti];
11026            opti++;
11027            if ("activities".equals(cmd) || "a".equals(cmd)) {
11028                synchronized (this) {
11029                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11030                }
11031            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11032                String[] newArgs;
11033                String name;
11034                if (opti >= args.length) {
11035                    name = null;
11036                    newArgs = EMPTY_STRING_ARRAY;
11037                } else {
11038                    name = args[opti];
11039                    opti++;
11040                    newArgs = new String[args.length - opti];
11041                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11042                            args.length - opti);
11043                }
11044                synchronized (this) {
11045                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11046                }
11047            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11048                String[] newArgs;
11049                String name;
11050                if (opti >= args.length) {
11051                    name = null;
11052                    newArgs = EMPTY_STRING_ARRAY;
11053                } else {
11054                    name = args[opti];
11055                    opti++;
11056                    newArgs = new String[args.length - opti];
11057                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11058                            args.length - opti);
11059                }
11060                synchronized (this) {
11061                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11062                }
11063            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11064                String[] newArgs;
11065                String name;
11066                if (opti >= args.length) {
11067                    name = null;
11068                    newArgs = EMPTY_STRING_ARRAY;
11069                } else {
11070                    name = args[opti];
11071                    opti++;
11072                    newArgs = new String[args.length - opti];
11073                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11074                            args.length - opti);
11075                }
11076                synchronized (this) {
11077                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11078                }
11079            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11080                synchronized (this) {
11081                    dumpOomLocked(fd, pw, args, opti, true);
11082                }
11083            } else if ("provider".equals(cmd)) {
11084                String[] newArgs;
11085                String name;
11086                if (opti >= args.length) {
11087                    name = null;
11088                    newArgs = EMPTY_STRING_ARRAY;
11089                } else {
11090                    name = args[opti];
11091                    opti++;
11092                    newArgs = new String[args.length - opti];
11093                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11094                }
11095                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11096                    pw.println("No providers match: " + name);
11097                    pw.println("Use -h for help.");
11098                }
11099            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11100                synchronized (this) {
11101                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11102                }
11103            } else if ("service".equals(cmd)) {
11104                String[] newArgs;
11105                String name;
11106                if (opti >= args.length) {
11107                    name = null;
11108                    newArgs = EMPTY_STRING_ARRAY;
11109                } else {
11110                    name = args[opti];
11111                    opti++;
11112                    newArgs = new String[args.length - opti];
11113                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11114                            args.length - opti);
11115                }
11116                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11117                    pw.println("No services match: " + name);
11118                    pw.println("Use -h for help.");
11119                }
11120            } else if ("package".equals(cmd)) {
11121                String[] newArgs;
11122                if (opti >= args.length) {
11123                    pw.println("package: no package name specified");
11124                    pw.println("Use -h for help.");
11125                } else {
11126                    dumpPackage = args[opti];
11127                    opti++;
11128                    newArgs = new String[args.length - opti];
11129                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11130                            args.length - opti);
11131                    args = newArgs;
11132                    opti = 0;
11133                    more = true;
11134                }
11135            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11136                synchronized (this) {
11137                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11138                }
11139            } else {
11140                // Dumping a single activity?
11141                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11142                    pw.println("Bad activity command, or no activities match: " + cmd);
11143                    pw.println("Use -h for help.");
11144                }
11145            }
11146            if (!more) {
11147                Binder.restoreCallingIdentity(origId);
11148                return;
11149            }
11150        }
11151
11152        // No piece of data specified, dump everything.
11153        synchronized (this) {
11154            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11155            pw.println();
11156            if (dumpAll) {
11157                pw.println("-------------------------------------------------------------------------------");
11158            }
11159            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11160            pw.println();
11161            if (dumpAll) {
11162                pw.println("-------------------------------------------------------------------------------");
11163            }
11164            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11165            pw.println();
11166            if (dumpAll) {
11167                pw.println("-------------------------------------------------------------------------------");
11168            }
11169            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11170            pw.println();
11171            if (dumpAll) {
11172                pw.println("-------------------------------------------------------------------------------");
11173            }
11174            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11175            pw.println();
11176            if (dumpAll) {
11177                pw.println("-------------------------------------------------------------------------------");
11178            }
11179            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11180        }
11181        Binder.restoreCallingIdentity(origId);
11182    }
11183
11184    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11185            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11186        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11187
11188        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11189                dumpPackage);
11190        boolean needSep = printedAnything;
11191
11192        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11193                dumpPackage, needSep, "  mFocusedActivity: ");
11194        if (printed) {
11195            printedAnything = true;
11196            needSep = false;
11197        }
11198
11199        if (dumpPackage == null) {
11200            if (needSep) {
11201                pw.println();
11202            }
11203            needSep = true;
11204            printedAnything = true;
11205            mStackSupervisor.dump(pw, "  ");
11206        }
11207
11208        if (mRecentTasks.size() > 0) {
11209            boolean printedHeader = false;
11210
11211            final int N = mRecentTasks.size();
11212            for (int i=0; i<N; i++) {
11213                TaskRecord tr = mRecentTasks.get(i);
11214                if (dumpPackage != null) {
11215                    if (tr.realActivity == null ||
11216                            !dumpPackage.equals(tr.realActivity)) {
11217                        continue;
11218                    }
11219                }
11220                if (!printedHeader) {
11221                    if (needSep) {
11222                        pw.println();
11223                    }
11224                    pw.println("  Recent tasks:");
11225                    printedHeader = true;
11226                    printedAnything = true;
11227                }
11228                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11229                        pw.println(tr);
11230                if (dumpAll) {
11231                    mRecentTasks.get(i).dump(pw, "    ");
11232                }
11233            }
11234        }
11235
11236        if (!printedAnything) {
11237            pw.println("  (nothing)");
11238        }
11239    }
11240
11241    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11242            int opti, boolean dumpAll, String dumpPackage) {
11243        boolean needSep = false;
11244        boolean printedAnything = false;
11245        int numPers = 0;
11246
11247        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11248
11249        if (dumpAll) {
11250            final int NP = mProcessNames.getMap().size();
11251            for (int ip=0; ip<NP; ip++) {
11252                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11253                final int NA = procs.size();
11254                for (int ia=0; ia<NA; ia++) {
11255                    ProcessRecord r = procs.valueAt(ia);
11256                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11257                        continue;
11258                    }
11259                    if (!needSep) {
11260                        pw.println("  All known processes:");
11261                        needSep = true;
11262                        printedAnything = true;
11263                    }
11264                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11265                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11266                        pw.print(" "); pw.println(r);
11267                    r.dump(pw, "    ");
11268                    if (r.persistent) {
11269                        numPers++;
11270                    }
11271                }
11272            }
11273        }
11274
11275        if (mIsolatedProcesses.size() > 0) {
11276            boolean printed = false;
11277            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11278                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11279                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11280                    continue;
11281                }
11282                if (!printed) {
11283                    if (needSep) {
11284                        pw.println();
11285                    }
11286                    pw.println("  Isolated process list (sorted by uid):");
11287                    printedAnything = true;
11288                    printed = true;
11289                    needSep = true;
11290                }
11291                pw.println(String.format("%sIsolated #%2d: %s",
11292                        "    ", i, r.toString()));
11293            }
11294        }
11295
11296        if (mLruProcesses.size() > 0) {
11297            if (needSep) {
11298                pw.println();
11299            }
11300            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11301                    pw.print(" total, non-act at ");
11302                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11303                    pw.print(", non-svc at ");
11304                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11305                    pw.println("):");
11306            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11307            needSep = true;
11308            printedAnything = true;
11309        }
11310
11311        if (dumpAll || dumpPackage != null) {
11312            synchronized (mPidsSelfLocked) {
11313                boolean printed = false;
11314                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11315                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11316                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11317                        continue;
11318                    }
11319                    if (!printed) {
11320                        if (needSep) pw.println();
11321                        needSep = true;
11322                        pw.println("  PID mappings:");
11323                        printed = true;
11324                        printedAnything = true;
11325                    }
11326                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11327                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11328                }
11329            }
11330        }
11331
11332        if (mForegroundProcesses.size() > 0) {
11333            synchronized (mPidsSelfLocked) {
11334                boolean printed = false;
11335                for (int i=0; i<mForegroundProcesses.size(); i++) {
11336                    ProcessRecord r = mPidsSelfLocked.get(
11337                            mForegroundProcesses.valueAt(i).pid);
11338                    if (dumpPackage != null && (r == null
11339                            || !r.pkgList.containsKey(dumpPackage))) {
11340                        continue;
11341                    }
11342                    if (!printed) {
11343                        if (needSep) pw.println();
11344                        needSep = true;
11345                        pw.println("  Foreground Processes:");
11346                        printed = true;
11347                        printedAnything = true;
11348                    }
11349                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11350                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11351                }
11352            }
11353        }
11354
11355        if (mPersistentStartingProcesses.size() > 0) {
11356            if (needSep) pw.println();
11357            needSep = true;
11358            printedAnything = true;
11359            pw.println("  Persisent processes that are starting:");
11360            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11361                    "Starting Norm", "Restarting PERS", dumpPackage);
11362        }
11363
11364        if (mRemovedProcesses.size() > 0) {
11365            if (needSep) pw.println();
11366            needSep = true;
11367            printedAnything = true;
11368            pw.println("  Processes that are being removed:");
11369            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11370                    "Removed Norm", "Removed PERS", dumpPackage);
11371        }
11372
11373        if (mProcessesOnHold.size() > 0) {
11374            if (needSep) pw.println();
11375            needSep = true;
11376            printedAnything = true;
11377            pw.println("  Processes that are on old until the system is ready:");
11378            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11379                    "OnHold Norm", "OnHold PERS", dumpPackage);
11380        }
11381
11382        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11383
11384        if (mProcessCrashTimes.getMap().size() > 0) {
11385            boolean printed = false;
11386            long now = SystemClock.uptimeMillis();
11387            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11388            final int NP = pmap.size();
11389            for (int ip=0; ip<NP; ip++) {
11390                String pname = pmap.keyAt(ip);
11391                SparseArray<Long> uids = pmap.valueAt(ip);
11392                final int N = uids.size();
11393                for (int i=0; i<N; i++) {
11394                    int puid = uids.keyAt(i);
11395                    ProcessRecord r = mProcessNames.get(pname, puid);
11396                    if (dumpPackage != null && (r == null
11397                            || !r.pkgList.containsKey(dumpPackage))) {
11398                        continue;
11399                    }
11400                    if (!printed) {
11401                        if (needSep) pw.println();
11402                        needSep = true;
11403                        pw.println("  Time since processes crashed:");
11404                        printed = true;
11405                        printedAnything = true;
11406                    }
11407                    pw.print("    Process "); pw.print(pname);
11408                            pw.print(" uid "); pw.print(puid);
11409                            pw.print(": last crashed ");
11410                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11411                            pw.println(" ago");
11412                }
11413            }
11414        }
11415
11416        if (mBadProcesses.getMap().size() > 0) {
11417            boolean printed = false;
11418            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11419            final int NP = pmap.size();
11420            for (int ip=0; ip<NP; ip++) {
11421                String pname = pmap.keyAt(ip);
11422                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11423                final int N = uids.size();
11424                for (int i=0; i<N; i++) {
11425                    int puid = uids.keyAt(i);
11426                    ProcessRecord r = mProcessNames.get(pname, puid);
11427                    if (dumpPackage != null && (r == null
11428                            || !r.pkgList.containsKey(dumpPackage))) {
11429                        continue;
11430                    }
11431                    if (!printed) {
11432                        if (needSep) pw.println();
11433                        needSep = true;
11434                        pw.println("  Bad processes:");
11435                        printedAnything = true;
11436                    }
11437                    BadProcessInfo info = uids.valueAt(i);
11438                    pw.print("    Bad process "); pw.print(pname);
11439                            pw.print(" uid "); pw.print(puid);
11440                            pw.print(": crashed at time "); pw.println(info.time);
11441                    if (info.shortMsg != null) {
11442                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11443                    }
11444                    if (info.longMsg != null) {
11445                        pw.print("      Long msg: "); pw.println(info.longMsg);
11446                    }
11447                    if (info.stack != null) {
11448                        pw.println("      Stack:");
11449                        int lastPos = 0;
11450                        for (int pos=0; pos<info.stack.length(); pos++) {
11451                            if (info.stack.charAt(pos) == '\n') {
11452                                pw.print("        ");
11453                                pw.write(info.stack, lastPos, pos-lastPos);
11454                                pw.println();
11455                                lastPos = pos+1;
11456                            }
11457                        }
11458                        if (lastPos < info.stack.length()) {
11459                            pw.print("        ");
11460                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11461                            pw.println();
11462                        }
11463                    }
11464                }
11465            }
11466        }
11467
11468        if (dumpPackage == null) {
11469            pw.println();
11470            needSep = false;
11471            pw.println("  mStartedUsers:");
11472            for (int i=0; i<mStartedUsers.size(); i++) {
11473                UserStartedState uss = mStartedUsers.valueAt(i);
11474                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11475                        pw.print(": "); uss.dump("", pw);
11476            }
11477            pw.print("  mStartedUserArray: [");
11478            for (int i=0; i<mStartedUserArray.length; i++) {
11479                if (i > 0) pw.print(", ");
11480                pw.print(mStartedUserArray[i]);
11481            }
11482            pw.println("]");
11483            pw.print("  mUserLru: [");
11484            for (int i=0; i<mUserLru.size(); i++) {
11485                if (i > 0) pw.print(", ");
11486                pw.print(mUserLru.get(i));
11487            }
11488            pw.println("]");
11489            if (dumpAll) {
11490                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11491            }
11492        }
11493        if (mHomeProcess != null && (dumpPackage == null
11494                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11495            if (needSep) {
11496                pw.println();
11497                needSep = false;
11498            }
11499            pw.println("  mHomeProcess: " + mHomeProcess);
11500        }
11501        if (mPreviousProcess != null && (dumpPackage == null
11502                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11503            if (needSep) {
11504                pw.println();
11505                needSep = false;
11506            }
11507            pw.println("  mPreviousProcess: " + mPreviousProcess);
11508        }
11509        if (dumpAll) {
11510            StringBuilder sb = new StringBuilder(128);
11511            sb.append("  mPreviousProcessVisibleTime: ");
11512            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11513            pw.println(sb);
11514        }
11515        if (mHeavyWeightProcess != null && (dumpPackage == null
11516                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11517            if (needSep) {
11518                pw.println();
11519                needSep = false;
11520            }
11521            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11522        }
11523        if (dumpPackage == null) {
11524            pw.println("  mConfiguration: " + mConfiguration);
11525        }
11526        if (dumpAll) {
11527            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11528            if (mCompatModePackages.getPackages().size() > 0) {
11529                boolean printed = false;
11530                for (Map.Entry<String, Integer> entry
11531                        : mCompatModePackages.getPackages().entrySet()) {
11532                    String pkg = entry.getKey();
11533                    int mode = entry.getValue();
11534                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11535                        continue;
11536                    }
11537                    if (!printed) {
11538                        pw.println("  mScreenCompatPackages:");
11539                        printed = true;
11540                    }
11541                    pw.print("    "); pw.print(pkg); pw.print(": ");
11542                            pw.print(mode); pw.println();
11543                }
11544            }
11545        }
11546        if (dumpPackage == null) {
11547            if (mSleeping || mWentToSleep || mLockScreenShown) {
11548                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11549                        + " mLockScreenShown " + mLockScreenShown);
11550            }
11551            if (mShuttingDown || mRunningVoice) {
11552                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11553            }
11554        }
11555        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11556                || mOrigWaitForDebugger) {
11557            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11558                    || dumpPackage.equals(mOrigDebugApp)) {
11559                if (needSep) {
11560                    pw.println();
11561                    needSep = false;
11562                }
11563                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11564                        + " mDebugTransient=" + mDebugTransient
11565                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11566            }
11567        }
11568        if (mOpenGlTraceApp != null) {
11569            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11570                if (needSep) {
11571                    pw.println();
11572                    needSep = false;
11573                }
11574                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11575            }
11576        }
11577        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11578                || mProfileFd != null) {
11579            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11580                if (needSep) {
11581                    pw.println();
11582                    needSep = false;
11583                }
11584                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11585                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11586                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11587                        + mAutoStopProfiler);
11588            }
11589        }
11590        if (dumpPackage == null) {
11591            if (mAlwaysFinishActivities || mController != null) {
11592                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11593                        + " mController=" + mController);
11594            }
11595            if (dumpAll) {
11596                pw.println("  Total persistent processes: " + numPers);
11597                pw.println("  mProcessesReady=" + mProcessesReady
11598                        + " mSystemReady=" + mSystemReady);
11599                pw.println("  mBooting=" + mBooting
11600                        + " mBooted=" + mBooted
11601                        + " mFactoryTest=" + mFactoryTest);
11602                pw.print("  mLastPowerCheckRealtime=");
11603                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11604                        pw.println("");
11605                pw.print("  mLastPowerCheckUptime=");
11606                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11607                        pw.println("");
11608                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11609                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11610                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11611                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11612                        + " (" + mLruProcesses.size() + " total)"
11613                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11614                        + " mNumServiceProcs=" + mNumServiceProcs
11615                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11616                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11617                        + " mLastMemoryLevel" + mLastMemoryLevel
11618                        + " mLastNumProcesses" + mLastNumProcesses);
11619                long now = SystemClock.uptimeMillis();
11620                pw.print("  mLastIdleTime=");
11621                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11622                        pw.print(" mLowRamSinceLastIdle=");
11623                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11624                        pw.println();
11625            }
11626        }
11627
11628        if (!printedAnything) {
11629            pw.println("  (nothing)");
11630        }
11631    }
11632
11633    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11634            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11635        if (mProcessesToGc.size() > 0) {
11636            boolean printed = false;
11637            long now = SystemClock.uptimeMillis();
11638            for (int i=0; i<mProcessesToGc.size(); i++) {
11639                ProcessRecord proc = mProcessesToGc.get(i);
11640                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11641                    continue;
11642                }
11643                if (!printed) {
11644                    if (needSep) pw.println();
11645                    needSep = true;
11646                    pw.println("  Processes that are waiting to GC:");
11647                    printed = true;
11648                }
11649                pw.print("    Process "); pw.println(proc);
11650                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11651                        pw.print(", last gced=");
11652                        pw.print(now-proc.lastRequestedGc);
11653                        pw.print(" ms ago, last lowMem=");
11654                        pw.print(now-proc.lastLowMemory);
11655                        pw.println(" ms ago");
11656
11657            }
11658        }
11659        return needSep;
11660    }
11661
11662    void printOomLevel(PrintWriter pw, String name, int adj) {
11663        pw.print("    ");
11664        if (adj >= 0) {
11665            pw.print(' ');
11666            if (adj < 10) pw.print(' ');
11667        } else {
11668            if (adj > -10) pw.print(' ');
11669        }
11670        pw.print(adj);
11671        pw.print(": ");
11672        pw.print(name);
11673        pw.print(" (");
11674        pw.print(mProcessList.getMemLevel(adj)/1024);
11675        pw.println(" kB)");
11676    }
11677
11678    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11679            int opti, boolean dumpAll) {
11680        boolean needSep = false;
11681
11682        if (mLruProcesses.size() > 0) {
11683            if (needSep) pw.println();
11684            needSep = true;
11685            pw.println("  OOM levels:");
11686            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11687            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11688            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11689            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11690            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11691            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11692            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11693            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11694            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11695            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11696            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11697            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11698            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11699
11700            if (needSep) pw.println();
11701            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11702                    pw.print(" total, non-act at ");
11703                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11704                    pw.print(", non-svc at ");
11705                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11706                    pw.println("):");
11707            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11708            needSep = true;
11709        }
11710
11711        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11712
11713        pw.println();
11714        pw.println("  mHomeProcess: " + mHomeProcess);
11715        pw.println("  mPreviousProcess: " + mPreviousProcess);
11716        if (mHeavyWeightProcess != null) {
11717            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11718        }
11719
11720        return true;
11721    }
11722
11723    /**
11724     * There are three ways to call this:
11725     *  - no provider specified: dump all the providers
11726     *  - a flattened component name that matched an existing provider was specified as the
11727     *    first arg: dump that one provider
11728     *  - the first arg isn't the flattened component name of an existing provider:
11729     *    dump all providers whose component contains the first arg as a substring
11730     */
11731    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11732            int opti, boolean dumpAll) {
11733        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11734    }
11735
11736    static class ItemMatcher {
11737        ArrayList<ComponentName> components;
11738        ArrayList<String> strings;
11739        ArrayList<Integer> objects;
11740        boolean all;
11741
11742        ItemMatcher() {
11743            all = true;
11744        }
11745
11746        void build(String name) {
11747            ComponentName componentName = ComponentName.unflattenFromString(name);
11748            if (componentName != null) {
11749                if (components == null) {
11750                    components = new ArrayList<ComponentName>();
11751                }
11752                components.add(componentName);
11753                all = false;
11754            } else {
11755                int objectId = 0;
11756                // Not a '/' separated full component name; maybe an object ID?
11757                try {
11758                    objectId = Integer.parseInt(name, 16);
11759                    if (objects == null) {
11760                        objects = new ArrayList<Integer>();
11761                    }
11762                    objects.add(objectId);
11763                    all = false;
11764                } catch (RuntimeException e) {
11765                    // Not an integer; just do string match.
11766                    if (strings == null) {
11767                        strings = new ArrayList<String>();
11768                    }
11769                    strings.add(name);
11770                    all = false;
11771                }
11772            }
11773        }
11774
11775        int build(String[] args, int opti) {
11776            for (; opti<args.length; opti++) {
11777                String name = args[opti];
11778                if ("--".equals(name)) {
11779                    return opti+1;
11780                }
11781                build(name);
11782            }
11783            return opti;
11784        }
11785
11786        boolean match(Object object, ComponentName comp) {
11787            if (all) {
11788                return true;
11789            }
11790            if (components != null) {
11791                for (int i=0; i<components.size(); i++) {
11792                    if (components.get(i).equals(comp)) {
11793                        return true;
11794                    }
11795                }
11796            }
11797            if (objects != null) {
11798                for (int i=0; i<objects.size(); i++) {
11799                    if (System.identityHashCode(object) == objects.get(i)) {
11800                        return true;
11801                    }
11802                }
11803            }
11804            if (strings != null) {
11805                String flat = comp.flattenToString();
11806                for (int i=0; i<strings.size(); i++) {
11807                    if (flat.contains(strings.get(i))) {
11808                        return true;
11809                    }
11810                }
11811            }
11812            return false;
11813        }
11814    }
11815
11816    /**
11817     * There are three things that cmd can be:
11818     *  - a flattened component name that matches an existing activity
11819     *  - the cmd arg isn't the flattened component name of an existing activity:
11820     *    dump all activity whose component contains the cmd as a substring
11821     *  - A hex number of the ActivityRecord object instance.
11822     */
11823    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11824            int opti, boolean dumpAll) {
11825        ArrayList<ActivityRecord> activities;
11826
11827        synchronized (this) {
11828            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11829        }
11830
11831        if (activities.size() <= 0) {
11832            return false;
11833        }
11834
11835        String[] newArgs = new String[args.length - opti];
11836        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11837
11838        TaskRecord lastTask = null;
11839        boolean needSep = false;
11840        for (int i=activities.size()-1; i>=0; i--) {
11841            ActivityRecord r = activities.get(i);
11842            if (needSep) {
11843                pw.println();
11844            }
11845            needSep = true;
11846            synchronized (this) {
11847                if (lastTask != r.task) {
11848                    lastTask = r.task;
11849                    pw.print("TASK "); pw.print(lastTask.affinity);
11850                            pw.print(" id="); pw.println(lastTask.taskId);
11851                    if (dumpAll) {
11852                        lastTask.dump(pw, "  ");
11853                    }
11854                }
11855            }
11856            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11857        }
11858        return true;
11859    }
11860
11861    /**
11862     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11863     * there is a thread associated with the activity.
11864     */
11865    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11866            final ActivityRecord r, String[] args, boolean dumpAll) {
11867        String innerPrefix = prefix + "  ";
11868        synchronized (this) {
11869            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11870                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11871                    pw.print(" pid=");
11872                    if (r.app != null) pw.println(r.app.pid);
11873                    else pw.println("(not running)");
11874            if (dumpAll) {
11875                r.dump(pw, innerPrefix);
11876            }
11877        }
11878        if (r.app != null && r.app.thread != null) {
11879            // flush anything that is already in the PrintWriter since the thread is going
11880            // to write to the file descriptor directly
11881            pw.flush();
11882            try {
11883                TransferPipe tp = new TransferPipe();
11884                try {
11885                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11886                            r.appToken, innerPrefix, args);
11887                    tp.go(fd);
11888                } finally {
11889                    tp.kill();
11890                }
11891            } catch (IOException e) {
11892                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11893            } catch (RemoteException e) {
11894                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11895            }
11896        }
11897    }
11898
11899    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11900            int opti, boolean dumpAll, String dumpPackage) {
11901        boolean needSep = false;
11902        boolean onlyHistory = false;
11903        boolean printedAnything = false;
11904
11905        if ("history".equals(dumpPackage)) {
11906            if (opti < args.length && "-s".equals(args[opti])) {
11907                dumpAll = false;
11908            }
11909            onlyHistory = true;
11910            dumpPackage = null;
11911        }
11912
11913        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11914        if (!onlyHistory && dumpAll) {
11915            if (mRegisteredReceivers.size() > 0) {
11916                boolean printed = false;
11917                Iterator it = mRegisteredReceivers.values().iterator();
11918                while (it.hasNext()) {
11919                    ReceiverList r = (ReceiverList)it.next();
11920                    if (dumpPackage != null && (r.app == null ||
11921                            !dumpPackage.equals(r.app.info.packageName))) {
11922                        continue;
11923                    }
11924                    if (!printed) {
11925                        pw.println("  Registered Receivers:");
11926                        needSep = true;
11927                        printed = true;
11928                        printedAnything = true;
11929                    }
11930                    pw.print("  * "); pw.println(r);
11931                    r.dump(pw, "    ");
11932                }
11933            }
11934
11935            if (mReceiverResolver.dump(pw, needSep ?
11936                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11937                    "    ", dumpPackage, false)) {
11938                needSep = true;
11939                printedAnything = true;
11940            }
11941        }
11942
11943        for (BroadcastQueue q : mBroadcastQueues) {
11944            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11945            printedAnything |= needSep;
11946        }
11947
11948        needSep = true;
11949
11950        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11951            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11952                if (needSep) {
11953                    pw.println();
11954                }
11955                needSep = true;
11956                printedAnything = true;
11957                pw.print("  Sticky broadcasts for user ");
11958                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11959                StringBuilder sb = new StringBuilder(128);
11960                for (Map.Entry<String, ArrayList<Intent>> ent
11961                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11962                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11963                    if (dumpAll) {
11964                        pw.println(":");
11965                        ArrayList<Intent> intents = ent.getValue();
11966                        final int N = intents.size();
11967                        for (int i=0; i<N; i++) {
11968                            sb.setLength(0);
11969                            sb.append("    Intent: ");
11970                            intents.get(i).toShortString(sb, false, true, false, false);
11971                            pw.println(sb.toString());
11972                            Bundle bundle = intents.get(i).getExtras();
11973                            if (bundle != null) {
11974                                pw.print("      ");
11975                                pw.println(bundle.toString());
11976                            }
11977                        }
11978                    } else {
11979                        pw.println("");
11980                    }
11981                }
11982            }
11983        }
11984
11985        if (!onlyHistory && dumpAll) {
11986            pw.println();
11987            for (BroadcastQueue queue : mBroadcastQueues) {
11988                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11989                        + queue.mBroadcastsScheduled);
11990            }
11991            pw.println("  mHandler:");
11992            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11993            needSep = true;
11994            printedAnything = true;
11995        }
11996
11997        if (!printedAnything) {
11998            pw.println("  (nothing)");
11999        }
12000    }
12001
12002    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12003            int opti, boolean dumpAll, String dumpPackage) {
12004        boolean needSep;
12005        boolean printedAnything = false;
12006
12007        ItemMatcher matcher = new ItemMatcher();
12008        matcher.build(args, opti);
12009
12010        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12011
12012        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12013        printedAnything |= needSep;
12014
12015        if (mLaunchingProviders.size() > 0) {
12016            boolean printed = false;
12017            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12018                ContentProviderRecord r = mLaunchingProviders.get(i);
12019                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12020                    continue;
12021                }
12022                if (!printed) {
12023                    if (needSep) pw.println();
12024                    needSep = true;
12025                    pw.println("  Launching content providers:");
12026                    printed = true;
12027                    printedAnything = true;
12028                }
12029                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12030                        pw.println(r);
12031            }
12032        }
12033
12034        if (mGrantedUriPermissions.size() > 0) {
12035            boolean printed = false;
12036            int dumpUid = -2;
12037            if (dumpPackage != null) {
12038                try {
12039                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12040                } catch (NameNotFoundException e) {
12041                    dumpUid = -1;
12042                }
12043            }
12044            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12045                int uid = mGrantedUriPermissions.keyAt(i);
12046                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12047                    continue;
12048                }
12049                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12050                if (!printed) {
12051                    if (needSep) pw.println();
12052                    needSep = true;
12053                    pw.println("  Granted Uri Permissions:");
12054                    printed = true;
12055                    printedAnything = true;
12056                }
12057                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12058                for (UriPermission perm : perms.values()) {
12059                    pw.print("    "); pw.println(perm);
12060                    if (dumpAll) {
12061                        perm.dump(pw, "      ");
12062                    }
12063                }
12064            }
12065        }
12066
12067        if (!printedAnything) {
12068            pw.println("  (nothing)");
12069        }
12070    }
12071
12072    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12073            int opti, boolean dumpAll, String dumpPackage) {
12074        boolean printed = false;
12075
12076        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12077
12078        if (mIntentSenderRecords.size() > 0) {
12079            Iterator<WeakReference<PendingIntentRecord>> it
12080                    = mIntentSenderRecords.values().iterator();
12081            while (it.hasNext()) {
12082                WeakReference<PendingIntentRecord> ref = it.next();
12083                PendingIntentRecord rec = ref != null ? ref.get(): null;
12084                if (dumpPackage != null && (rec == null
12085                        || !dumpPackage.equals(rec.key.packageName))) {
12086                    continue;
12087                }
12088                printed = true;
12089                if (rec != null) {
12090                    pw.print("  * "); pw.println(rec);
12091                    if (dumpAll) {
12092                        rec.dump(pw, "    ");
12093                    }
12094                } else {
12095                    pw.print("  * "); pw.println(ref);
12096                }
12097            }
12098        }
12099
12100        if (!printed) {
12101            pw.println("  (nothing)");
12102        }
12103    }
12104
12105    private static final int dumpProcessList(PrintWriter pw,
12106            ActivityManagerService service, List list,
12107            String prefix, String normalLabel, String persistentLabel,
12108            String dumpPackage) {
12109        int numPers = 0;
12110        final int N = list.size()-1;
12111        for (int i=N; i>=0; i--) {
12112            ProcessRecord r = (ProcessRecord)list.get(i);
12113            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12114                continue;
12115            }
12116            pw.println(String.format("%s%s #%2d: %s",
12117                    prefix, (r.persistent ? persistentLabel : normalLabel),
12118                    i, r.toString()));
12119            if (r.persistent) {
12120                numPers++;
12121            }
12122        }
12123        return numPers;
12124    }
12125
12126    private static final boolean dumpProcessOomList(PrintWriter pw,
12127            ActivityManagerService service, List<ProcessRecord> origList,
12128            String prefix, String normalLabel, String persistentLabel,
12129            boolean inclDetails, String dumpPackage) {
12130
12131        ArrayList<Pair<ProcessRecord, Integer>> list
12132                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12133        for (int i=0; i<origList.size(); i++) {
12134            ProcessRecord r = origList.get(i);
12135            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12136                continue;
12137            }
12138            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12139        }
12140
12141        if (list.size() <= 0) {
12142            return false;
12143        }
12144
12145        Comparator<Pair<ProcessRecord, Integer>> comparator
12146                = new Comparator<Pair<ProcessRecord, Integer>>() {
12147            @Override
12148            public int compare(Pair<ProcessRecord, Integer> object1,
12149                    Pair<ProcessRecord, Integer> object2) {
12150                if (object1.first.setAdj != object2.first.setAdj) {
12151                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12152                }
12153                if (object1.second.intValue() != object2.second.intValue()) {
12154                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12155                }
12156                return 0;
12157            }
12158        };
12159
12160        Collections.sort(list, comparator);
12161
12162        final long curRealtime = SystemClock.elapsedRealtime();
12163        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12164        final long curUptime = SystemClock.uptimeMillis();
12165        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12166
12167        for (int i=list.size()-1; i>=0; i--) {
12168            ProcessRecord r = list.get(i).first;
12169            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12170            char schedGroup;
12171            switch (r.setSchedGroup) {
12172                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12173                    schedGroup = 'B';
12174                    break;
12175                case Process.THREAD_GROUP_DEFAULT:
12176                    schedGroup = 'F';
12177                    break;
12178                default:
12179                    schedGroup = '?';
12180                    break;
12181            }
12182            char foreground;
12183            if (r.foregroundActivities) {
12184                foreground = 'A';
12185            } else if (r.foregroundServices) {
12186                foreground = 'S';
12187            } else {
12188                foreground = ' ';
12189            }
12190            String procState = ProcessList.makeProcStateString(r.curProcState);
12191            pw.print(prefix);
12192            pw.print(r.persistent ? persistentLabel : normalLabel);
12193            pw.print(" #");
12194            int num = (origList.size()-1)-list.get(i).second;
12195            if (num < 10) pw.print(' ');
12196            pw.print(num);
12197            pw.print(": ");
12198            pw.print(oomAdj);
12199            pw.print(' ');
12200            pw.print(schedGroup);
12201            pw.print('/');
12202            pw.print(foreground);
12203            pw.print('/');
12204            pw.print(procState);
12205            pw.print(" trm:");
12206            if (r.trimMemoryLevel < 10) pw.print(' ');
12207            pw.print(r.trimMemoryLevel);
12208            pw.print(' ');
12209            pw.print(r.toShortString());
12210            pw.print(" (");
12211            pw.print(r.adjType);
12212            pw.println(')');
12213            if (r.adjSource != null || r.adjTarget != null) {
12214                pw.print(prefix);
12215                pw.print("    ");
12216                if (r.adjTarget instanceof ComponentName) {
12217                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12218                } else if (r.adjTarget != null) {
12219                    pw.print(r.adjTarget.toString());
12220                } else {
12221                    pw.print("{null}");
12222                }
12223                pw.print("<=");
12224                if (r.adjSource instanceof ProcessRecord) {
12225                    pw.print("Proc{");
12226                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12227                    pw.println("}");
12228                } else if (r.adjSource != null) {
12229                    pw.println(r.adjSource.toString());
12230                } else {
12231                    pw.println("{null}");
12232                }
12233            }
12234            if (inclDetails) {
12235                pw.print(prefix);
12236                pw.print("    ");
12237                pw.print("oom: max="); pw.print(r.maxAdj);
12238                pw.print(" curRaw="); pw.print(r.curRawAdj);
12239                pw.print(" setRaw="); pw.print(r.setRawAdj);
12240                pw.print(" cur="); pw.print(r.curAdj);
12241                pw.print(" set="); pw.println(r.setAdj);
12242                pw.print(prefix);
12243                pw.print("    ");
12244                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12245                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12246                pw.print(" lastPss="); pw.print(r.lastPss);
12247                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12248                pw.print(prefix);
12249                pw.print("    ");
12250                pw.print("keeping="); pw.print(r.keeping);
12251                pw.print(" cached="); pw.print(r.cached);
12252                pw.print(" empty="); pw.print(r.empty);
12253                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12254
12255                if (!r.keeping) {
12256                    if (r.lastWakeTime != 0) {
12257                        long wtime;
12258                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12259                        synchronized (stats) {
12260                            wtime = stats.getProcessWakeTime(r.info.uid,
12261                                    r.pid, curRealtime);
12262                        }
12263                        long timeUsed = wtime - r.lastWakeTime;
12264                        pw.print(prefix);
12265                        pw.print("    ");
12266                        pw.print("keep awake over ");
12267                        TimeUtils.formatDuration(realtimeSince, pw);
12268                        pw.print(" used ");
12269                        TimeUtils.formatDuration(timeUsed, pw);
12270                        pw.print(" (");
12271                        pw.print((timeUsed*100)/realtimeSince);
12272                        pw.println("%)");
12273                    }
12274                    if (r.lastCpuTime != 0) {
12275                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12276                        pw.print(prefix);
12277                        pw.print("    ");
12278                        pw.print("run cpu over ");
12279                        TimeUtils.formatDuration(uptimeSince, pw);
12280                        pw.print(" used ");
12281                        TimeUtils.formatDuration(timeUsed, pw);
12282                        pw.print(" (");
12283                        pw.print((timeUsed*100)/uptimeSince);
12284                        pw.println("%)");
12285                    }
12286                }
12287            }
12288        }
12289        return true;
12290    }
12291
12292    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12293        ArrayList<ProcessRecord> procs;
12294        synchronized (this) {
12295            if (args != null && args.length > start
12296                    && args[start].charAt(0) != '-') {
12297                procs = new ArrayList<ProcessRecord>();
12298                int pid = -1;
12299                try {
12300                    pid = Integer.parseInt(args[start]);
12301                } catch (NumberFormatException e) {
12302                }
12303                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12304                    ProcessRecord proc = mLruProcesses.get(i);
12305                    if (proc.pid == pid) {
12306                        procs.add(proc);
12307                    } else if (proc.processName.equals(args[start])) {
12308                        procs.add(proc);
12309                    }
12310                }
12311                if (procs.size() <= 0) {
12312                    return null;
12313                }
12314            } else {
12315                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12316            }
12317        }
12318        return procs;
12319    }
12320
12321    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12322            PrintWriter pw, String[] args) {
12323        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12324        if (procs == null) {
12325            pw.println("No process found for: " + args[0]);
12326            return;
12327        }
12328
12329        long uptime = SystemClock.uptimeMillis();
12330        long realtime = SystemClock.elapsedRealtime();
12331        pw.println("Applications Graphics Acceleration Info:");
12332        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12333
12334        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12335            ProcessRecord r = procs.get(i);
12336            if (r.thread != null) {
12337                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12338                pw.flush();
12339                try {
12340                    TransferPipe tp = new TransferPipe();
12341                    try {
12342                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12343                        tp.go(fd);
12344                    } finally {
12345                        tp.kill();
12346                    }
12347                } catch (IOException e) {
12348                    pw.println("Failure while dumping the app: " + r);
12349                    pw.flush();
12350                } catch (RemoteException e) {
12351                    pw.println("Got a RemoteException while dumping the app " + r);
12352                    pw.flush();
12353                }
12354            }
12355        }
12356    }
12357
12358    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12359        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12360        if (procs == null) {
12361            pw.println("No process found for: " + args[0]);
12362            return;
12363        }
12364
12365        pw.println("Applications Database Info:");
12366
12367        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12368            ProcessRecord r = procs.get(i);
12369            if (r.thread != null) {
12370                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12371                pw.flush();
12372                try {
12373                    TransferPipe tp = new TransferPipe();
12374                    try {
12375                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12376                        tp.go(fd);
12377                    } finally {
12378                        tp.kill();
12379                    }
12380                } catch (IOException e) {
12381                    pw.println("Failure while dumping the app: " + r);
12382                    pw.flush();
12383                } catch (RemoteException e) {
12384                    pw.println("Got a RemoteException while dumping the app " + r);
12385                    pw.flush();
12386                }
12387            }
12388        }
12389    }
12390
12391    final static class MemItem {
12392        final boolean isProc;
12393        final String label;
12394        final String shortLabel;
12395        final long pss;
12396        final int id;
12397        final boolean hasActivities;
12398        ArrayList<MemItem> subitems;
12399
12400        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12401                boolean _hasActivities) {
12402            isProc = true;
12403            label = _label;
12404            shortLabel = _shortLabel;
12405            pss = _pss;
12406            id = _id;
12407            hasActivities = _hasActivities;
12408        }
12409
12410        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12411            isProc = false;
12412            label = _label;
12413            shortLabel = _shortLabel;
12414            pss = _pss;
12415            id = _id;
12416            hasActivities = false;
12417        }
12418    }
12419
12420    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12421            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12422        if (sort && !isCompact) {
12423            Collections.sort(items, new Comparator<MemItem>() {
12424                @Override
12425                public int compare(MemItem lhs, MemItem rhs) {
12426                    if (lhs.pss < rhs.pss) {
12427                        return 1;
12428                    } else if (lhs.pss > rhs.pss) {
12429                        return -1;
12430                    }
12431                    return 0;
12432                }
12433            });
12434        }
12435
12436        for (int i=0; i<items.size(); i++) {
12437            MemItem mi = items.get(i);
12438            if (!isCompact) {
12439                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12440            } else if (mi.isProc) {
12441                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12442                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12443                pw.println(mi.hasActivities ? ",a" : ",e");
12444            } else {
12445                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12446                pw.println(mi.pss);
12447            }
12448            if (mi.subitems != null) {
12449                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12450                        true, isCompact);
12451            }
12452        }
12453    }
12454
12455    // These are in KB.
12456    static final long[] DUMP_MEM_BUCKETS = new long[] {
12457        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12458        120*1024, 160*1024, 200*1024,
12459        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12460        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12461    };
12462
12463    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12464            boolean stackLike) {
12465        int start = label.lastIndexOf('.');
12466        if (start >= 0) start++;
12467        else start = 0;
12468        int end = label.length();
12469        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12470            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12471                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12472                out.append(bucket);
12473                out.append(stackLike ? "MB." : "MB ");
12474                out.append(label, start, end);
12475                return;
12476            }
12477        }
12478        out.append(memKB/1024);
12479        out.append(stackLike ? "MB." : "MB ");
12480        out.append(label, start, end);
12481    }
12482
12483    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12484            ProcessList.NATIVE_ADJ,
12485            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12486            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12487            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12488            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12489            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12490    };
12491    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12492            "Native",
12493            "System", "Persistent", "Foreground",
12494            "Visible", "Perceptible",
12495            "Heavy Weight", "Backup",
12496            "A Services", "Home",
12497            "Previous", "B Services", "Cached"
12498    };
12499    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12500            "native",
12501            "sys", "pers", "fore",
12502            "vis", "percept",
12503            "heavy", "backup",
12504            "servicea", "home",
12505            "prev", "serviceb", "cached"
12506    };
12507
12508    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12509            long realtime, boolean isCheckinRequest, boolean isCompact) {
12510        if (isCheckinRequest || isCompact) {
12511            // short checkin version
12512            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12513        } else {
12514            pw.println("Applications Memory Usage (kB):");
12515            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12516        }
12517    }
12518
12519    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12520            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12521        boolean dumpDetails = false;
12522        boolean dumpFullDetails = false;
12523        boolean dumpDalvik = false;
12524        boolean oomOnly = false;
12525        boolean isCompact = false;
12526        boolean localOnly = false;
12527
12528        int opti = 0;
12529        while (opti < args.length) {
12530            String opt = args[opti];
12531            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12532                break;
12533            }
12534            opti++;
12535            if ("-a".equals(opt)) {
12536                dumpDetails = true;
12537                dumpFullDetails = true;
12538                dumpDalvik = true;
12539            } else if ("-d".equals(opt)) {
12540                dumpDalvik = true;
12541            } else if ("-c".equals(opt)) {
12542                isCompact = true;
12543            } else if ("--oom".equals(opt)) {
12544                oomOnly = true;
12545            } else if ("--local".equals(opt)) {
12546                localOnly = true;
12547            } else if ("-h".equals(opt)) {
12548                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12549                pw.println("  -a: include all available information for each process.");
12550                pw.println("  -d: include dalvik details when dumping process details.");
12551                pw.println("  -c: dump in a compact machine-parseable representation.");
12552                pw.println("  --oom: only show processes organized by oom adj.");
12553                pw.println("  --local: only collect details locally, don't call process.");
12554                pw.println("If [process] is specified it can be the name or ");
12555                pw.println("pid of a specific process to dump.");
12556                return;
12557            } else {
12558                pw.println("Unknown argument: " + opt + "; use -h for help");
12559            }
12560        }
12561
12562        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12563        long uptime = SystemClock.uptimeMillis();
12564        long realtime = SystemClock.elapsedRealtime();
12565        final long[] tmpLong = new long[1];
12566
12567        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12568        if (procs == null) {
12569            // No Java processes.  Maybe they want to print a native process.
12570            if (args != null && args.length > opti
12571                    && args[opti].charAt(0) != '-') {
12572                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12573                        = new ArrayList<ProcessCpuTracker.Stats>();
12574                updateCpuStatsNow();
12575                int findPid = -1;
12576                try {
12577                    findPid = Integer.parseInt(args[opti]);
12578                } catch (NumberFormatException e) {
12579                }
12580                synchronized (mProcessCpuThread) {
12581                    final int N = mProcessCpuTracker.countStats();
12582                    for (int i=0; i<N; i++) {
12583                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12584                        if (st.pid == findPid || (st.baseName != null
12585                                && st.baseName.equals(args[opti]))) {
12586                            nativeProcs.add(st);
12587                        }
12588                    }
12589                }
12590                if (nativeProcs.size() > 0) {
12591                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12592                            isCompact);
12593                    Debug.MemoryInfo mi = null;
12594                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12595                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12596                        final int pid = r.pid;
12597                        if (!isCheckinRequest && dumpDetails) {
12598                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12599                        }
12600                        if (mi == null) {
12601                            mi = new Debug.MemoryInfo();
12602                        }
12603                        if (dumpDetails || (!brief && !oomOnly)) {
12604                            Debug.getMemoryInfo(pid, mi);
12605                        } else {
12606                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12607                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12608                        }
12609                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12610                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12611                        if (isCheckinRequest) {
12612                            pw.println();
12613                        }
12614                    }
12615                    return;
12616                }
12617            }
12618            pw.println("No process found for: " + args[opti]);
12619            return;
12620        }
12621
12622        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12623            dumpDetails = true;
12624        }
12625
12626        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12627
12628        String[] innerArgs = new String[args.length-opti];
12629        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12630
12631        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12632        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12633        long nativePss=0, dalvikPss=0, otherPss=0;
12634        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12635
12636        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12637        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12638                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12639
12640        long totalPss = 0;
12641        long cachedPss = 0;
12642
12643        Debug.MemoryInfo mi = null;
12644        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12645            final ProcessRecord r = procs.get(i);
12646            final IApplicationThread thread;
12647            final int pid;
12648            final int oomAdj;
12649            final boolean hasActivities;
12650            synchronized (this) {
12651                thread = r.thread;
12652                pid = r.pid;
12653                oomAdj = r.getSetAdjWithServices();
12654                hasActivities = r.activities.size() > 0;
12655            }
12656            if (thread != null) {
12657                if (!isCheckinRequest && dumpDetails) {
12658                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12659                }
12660                if (mi == null) {
12661                    mi = new Debug.MemoryInfo();
12662                }
12663                if (dumpDetails || (!brief && !oomOnly)) {
12664                    Debug.getMemoryInfo(pid, mi);
12665                } else {
12666                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12667                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12668                }
12669                if (dumpDetails) {
12670                    if (localOnly) {
12671                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12672                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12673                        if (isCheckinRequest) {
12674                            pw.println();
12675                        }
12676                    } else {
12677                        try {
12678                            pw.flush();
12679                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12680                                    dumpDalvik, innerArgs);
12681                        } catch (RemoteException e) {
12682                            if (!isCheckinRequest) {
12683                                pw.println("Got RemoteException!");
12684                                pw.flush();
12685                            }
12686                        }
12687                    }
12688                }
12689
12690                final long myTotalPss = mi.getTotalPss();
12691                final long myTotalUss = mi.getTotalUss();
12692
12693                synchronized (this) {
12694                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12695                        // Record this for posterity if the process has been stable.
12696                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12697                    }
12698                }
12699
12700                if (!isCheckinRequest && mi != null) {
12701                    totalPss += myTotalPss;
12702                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12703                            (hasActivities ? " / activities)" : ")"),
12704                            r.processName, myTotalPss, pid, hasActivities);
12705                    procMems.add(pssItem);
12706                    procMemsMap.put(pid, pssItem);
12707
12708                    nativePss += mi.nativePss;
12709                    dalvikPss += mi.dalvikPss;
12710                    otherPss += mi.otherPss;
12711                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12712                        long mem = mi.getOtherPss(j);
12713                        miscPss[j] += mem;
12714                        otherPss -= mem;
12715                    }
12716
12717                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12718                        cachedPss += myTotalPss;
12719                    }
12720
12721                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12722                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12723                                || oomIndex == (oomPss.length-1)) {
12724                            oomPss[oomIndex] += myTotalPss;
12725                            if (oomProcs[oomIndex] == null) {
12726                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12727                            }
12728                            oomProcs[oomIndex].add(pssItem);
12729                            break;
12730                        }
12731                    }
12732                }
12733            }
12734        }
12735
12736        long nativeProcTotalPss = 0;
12737
12738        if (!isCheckinRequest && procs.size() > 1) {
12739            // If we are showing aggregations, also look for native processes to
12740            // include so that our aggregations are more accurate.
12741            updateCpuStatsNow();
12742            synchronized (mProcessCpuThread) {
12743                final int N = mProcessCpuTracker.countStats();
12744                for (int i=0; i<N; i++) {
12745                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12746                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12747                        if (mi == null) {
12748                            mi = new Debug.MemoryInfo();
12749                        }
12750                        if (!brief && !oomOnly) {
12751                            Debug.getMemoryInfo(st.pid, mi);
12752                        } else {
12753                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12754                            mi.nativePrivateDirty = (int)tmpLong[0];
12755                        }
12756
12757                        final long myTotalPss = mi.getTotalPss();
12758                        totalPss += myTotalPss;
12759                        nativeProcTotalPss += myTotalPss;
12760
12761                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12762                                st.name, myTotalPss, st.pid, false);
12763                        procMems.add(pssItem);
12764
12765                        nativePss += mi.nativePss;
12766                        dalvikPss += mi.dalvikPss;
12767                        otherPss += mi.otherPss;
12768                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12769                            long mem = mi.getOtherPss(j);
12770                            miscPss[j] += mem;
12771                            otherPss -= mem;
12772                        }
12773                        oomPss[0] += myTotalPss;
12774                        if (oomProcs[0] == null) {
12775                            oomProcs[0] = new ArrayList<MemItem>();
12776                        }
12777                        oomProcs[0].add(pssItem);
12778                    }
12779                }
12780            }
12781
12782            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12783
12784            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12785            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12786            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12787            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12788                String label = Debug.MemoryInfo.getOtherLabel(j);
12789                catMems.add(new MemItem(label, label, miscPss[j], j));
12790            }
12791
12792            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12793            for (int j=0; j<oomPss.length; j++) {
12794                if (oomPss[j] != 0) {
12795                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12796                            : DUMP_MEM_OOM_LABEL[j];
12797                    MemItem item = new MemItem(label, label, oomPss[j],
12798                            DUMP_MEM_OOM_ADJ[j]);
12799                    item.subitems = oomProcs[j];
12800                    oomMems.add(item);
12801                }
12802            }
12803
12804            if (!brief && !oomOnly && !isCompact) {
12805                pw.println();
12806                pw.println("Total PSS by process:");
12807                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12808                pw.println();
12809            }
12810            if (!isCompact) {
12811                pw.println("Total PSS by OOM adjustment:");
12812            }
12813            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12814            if (!brief && !oomOnly) {
12815                PrintWriter out = categoryPw != null ? categoryPw : pw;
12816                if (!isCompact) {
12817                    out.println();
12818                    out.println("Total PSS by category:");
12819                }
12820                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12821            }
12822            if (!isCompact) {
12823                pw.println();
12824            }
12825            MemInfoReader memInfo = new MemInfoReader();
12826            memInfo.readMemInfo();
12827            if (nativeProcTotalPss > 0) {
12828                synchronized (this) {
12829                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
12830                            memInfo.getFreeSizeKb(),
12831                            memInfo.getSwapTotalSizeKb()-memInfo.getSwapFreeSizeKb(),
12832                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
12833                            nativeProcTotalPss);
12834                }
12835            }
12836            if (!brief) {
12837                if (!isCompact) {
12838                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12839                    pw.print(" kB (status ");
12840                    switch (mLastMemoryLevel) {
12841                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12842                            pw.println("normal)");
12843                            break;
12844                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12845                            pw.println("moderate)");
12846                            break;
12847                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12848                            pw.println("low)");
12849                            break;
12850                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12851                            pw.println("critical)");
12852                            break;
12853                        default:
12854                            pw.print(mLastMemoryLevel);
12855                            pw.println(")");
12856                            break;
12857                    }
12858                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12859                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12860                            pw.print(cachedPss); pw.print(" cached pss + ");
12861                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12862                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12863                } else {
12864                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12865                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12866                            + memInfo.getFreeSizeKb()); pw.print(",");
12867                    pw.println(totalPss - cachedPss);
12868                }
12869            }
12870            if (!isCompact) {
12871                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12872                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12873                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12874                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12875                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12876                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12877                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12878                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12879                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12880                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12881                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12882            }
12883            if (!brief) {
12884                if (memInfo.getZramTotalSizeKb() != 0) {
12885                    if (!isCompact) {
12886                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12887                                pw.print(" kB physical used for ");
12888                                pw.print(memInfo.getSwapTotalSizeKb()
12889                                        - memInfo.getSwapFreeSizeKb());
12890                                pw.print(" kB in swap (");
12891                                pw.print(memInfo.getSwapTotalSizeKb());
12892                                pw.println(" kB total swap)");
12893                    } else {
12894                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12895                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12896                                pw.println(memInfo.getSwapFreeSizeKb());
12897                    }
12898                }
12899                final int[] SINGLE_LONG_FORMAT = new int[] {
12900                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12901                };
12902                long[] longOut = new long[1];
12903                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12904                        SINGLE_LONG_FORMAT, null, longOut, null);
12905                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12906                longOut[0] = 0;
12907                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12908                        SINGLE_LONG_FORMAT, null, longOut, null);
12909                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12910                longOut[0] = 0;
12911                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12912                        SINGLE_LONG_FORMAT, null, longOut, null);
12913                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12914                longOut[0] = 0;
12915                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12916                        SINGLE_LONG_FORMAT, null, longOut, null);
12917                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12918                if (!isCompact) {
12919                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12920                        pw.print("      KSM: "); pw.print(sharing);
12921                                pw.print(" kB saved from shared ");
12922                                pw.print(shared); pw.println(" kB");
12923                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12924                                pw.print(voltile); pw.println(" kB volatile");
12925                    }
12926                    pw.print("   Tuning: ");
12927                    pw.print(ActivityManager.staticGetMemoryClass());
12928                    pw.print(" (large ");
12929                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12930                    pw.print("), oom ");
12931                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12932                    pw.print(" kB");
12933                    pw.print(", restore limit ");
12934                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12935                    pw.print(" kB");
12936                    if (ActivityManager.isLowRamDeviceStatic()) {
12937                        pw.print(" (low-ram)");
12938                    }
12939                    if (ActivityManager.isHighEndGfx()) {
12940                        pw.print(" (high-end-gfx)");
12941                    }
12942                    pw.println();
12943                } else {
12944                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12945                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12946                    pw.println(voltile);
12947                    pw.print("tuning,");
12948                    pw.print(ActivityManager.staticGetMemoryClass());
12949                    pw.print(',');
12950                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12951                    pw.print(',');
12952                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12953                    if (ActivityManager.isLowRamDeviceStatic()) {
12954                        pw.print(",low-ram");
12955                    }
12956                    if (ActivityManager.isHighEndGfx()) {
12957                        pw.print(",high-end-gfx");
12958                    }
12959                    pw.println();
12960                }
12961            }
12962        }
12963    }
12964
12965    /**
12966     * Searches array of arguments for the specified string
12967     * @param args array of argument strings
12968     * @param value value to search for
12969     * @return true if the value is contained in the array
12970     */
12971    private static boolean scanArgs(String[] args, String value) {
12972        if (args != null) {
12973            for (String arg : args) {
12974                if (value.equals(arg)) {
12975                    return true;
12976                }
12977            }
12978        }
12979        return false;
12980    }
12981
12982    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12983            ContentProviderRecord cpr, boolean always) {
12984        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12985
12986        if (!inLaunching || always) {
12987            synchronized (cpr) {
12988                cpr.launchingApp = null;
12989                cpr.notifyAll();
12990            }
12991            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12992            String names[] = cpr.info.authority.split(";");
12993            for (int j = 0; j < names.length; j++) {
12994                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12995            }
12996        }
12997
12998        for (int i=0; i<cpr.connections.size(); i++) {
12999            ContentProviderConnection conn = cpr.connections.get(i);
13000            if (conn.waiting) {
13001                // If this connection is waiting for the provider, then we don't
13002                // need to mess with its process unless we are always removing
13003                // or for some reason the provider is not currently launching.
13004                if (inLaunching && !always) {
13005                    continue;
13006                }
13007            }
13008            ProcessRecord capp = conn.client;
13009            conn.dead = true;
13010            if (conn.stableCount > 0) {
13011                if (!capp.persistent && capp.thread != null
13012                        && capp.pid != 0
13013                        && capp.pid != MY_PID) {
13014                    killUnneededProcessLocked(capp, "depends on provider "
13015                            + cpr.name.flattenToShortString()
13016                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13017                }
13018            } else if (capp.thread != null && conn.provider.provider != null) {
13019                try {
13020                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13021                } catch (RemoteException e) {
13022                }
13023                // In the protocol here, we don't expect the client to correctly
13024                // clean up this connection, we'll just remove it.
13025                cpr.connections.remove(i);
13026                conn.client.conProviders.remove(conn);
13027            }
13028        }
13029
13030        if (inLaunching && always) {
13031            mLaunchingProviders.remove(cpr);
13032        }
13033        return inLaunching;
13034    }
13035
13036    /**
13037     * Main code for cleaning up a process when it has gone away.  This is
13038     * called both as a result of the process dying, or directly when stopping
13039     * a process when running in single process mode.
13040     */
13041    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13042            boolean restarting, boolean allowRestart, int index) {
13043        if (index >= 0) {
13044            removeLruProcessLocked(app);
13045            ProcessList.remove(app.pid);
13046        }
13047
13048        mProcessesToGc.remove(app);
13049        mPendingPssProcesses.remove(app);
13050
13051        // Dismiss any open dialogs.
13052        if (app.crashDialog != null && !app.forceCrashReport) {
13053            app.crashDialog.dismiss();
13054            app.crashDialog = null;
13055        }
13056        if (app.anrDialog != null) {
13057            app.anrDialog.dismiss();
13058            app.anrDialog = null;
13059        }
13060        if (app.waitDialog != null) {
13061            app.waitDialog.dismiss();
13062            app.waitDialog = null;
13063        }
13064
13065        app.crashing = false;
13066        app.notResponding = false;
13067
13068        app.resetPackageList(mProcessStats);
13069        app.unlinkDeathRecipient();
13070        app.makeInactive(mProcessStats);
13071        app.forcingToForeground = null;
13072        updateProcessForegroundLocked(app, false, false);
13073        app.foregroundActivities = false;
13074        app.hasShownUi = false;
13075        app.treatLikeActivity = false;
13076        app.hasAboveClient = false;
13077        app.hasClientActivities = false;
13078
13079        mServices.killServicesLocked(app, allowRestart);
13080
13081        boolean restart = false;
13082
13083        // Remove published content providers.
13084        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13085            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13086            final boolean always = app.bad || !allowRestart;
13087            if (removeDyingProviderLocked(app, cpr, always) || always) {
13088                // We left the provider in the launching list, need to
13089                // restart it.
13090                restart = true;
13091            }
13092
13093            cpr.provider = null;
13094            cpr.proc = null;
13095        }
13096        app.pubProviders.clear();
13097
13098        // Take care of any launching providers waiting for this process.
13099        if (checkAppInLaunchingProvidersLocked(app, false)) {
13100            restart = true;
13101        }
13102
13103        // Unregister from connected content providers.
13104        if (!app.conProviders.isEmpty()) {
13105            for (int i=0; i<app.conProviders.size(); i++) {
13106                ContentProviderConnection conn = app.conProviders.get(i);
13107                conn.provider.connections.remove(conn);
13108            }
13109            app.conProviders.clear();
13110        }
13111
13112        // At this point there may be remaining entries in mLaunchingProviders
13113        // where we were the only one waiting, so they are no longer of use.
13114        // Look for these and clean up if found.
13115        // XXX Commented out for now.  Trying to figure out a way to reproduce
13116        // the actual situation to identify what is actually going on.
13117        if (false) {
13118            for (int i=0; i<mLaunchingProviders.size(); i++) {
13119                ContentProviderRecord cpr = (ContentProviderRecord)
13120                        mLaunchingProviders.get(i);
13121                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13122                    synchronized (cpr) {
13123                        cpr.launchingApp = null;
13124                        cpr.notifyAll();
13125                    }
13126                }
13127            }
13128        }
13129
13130        skipCurrentReceiverLocked(app);
13131
13132        // Unregister any receivers.
13133        for (int i=app.receivers.size()-1; i>=0; i--) {
13134            removeReceiverLocked(app.receivers.valueAt(i));
13135        }
13136        app.receivers.clear();
13137
13138        // If the app is undergoing backup, tell the backup manager about it
13139        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13140            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13141                    + mBackupTarget.appInfo + " died during backup");
13142            try {
13143                IBackupManager bm = IBackupManager.Stub.asInterface(
13144                        ServiceManager.getService(Context.BACKUP_SERVICE));
13145                bm.agentDisconnected(app.info.packageName);
13146            } catch (RemoteException e) {
13147                // can't happen; backup manager is local
13148            }
13149        }
13150
13151        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13152            ProcessChangeItem item = mPendingProcessChanges.get(i);
13153            if (item.pid == app.pid) {
13154                mPendingProcessChanges.remove(i);
13155                mAvailProcessChanges.add(item);
13156            }
13157        }
13158        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13159
13160        // If the caller is restarting this app, then leave it in its
13161        // current lists and let the caller take care of it.
13162        if (restarting) {
13163            return;
13164        }
13165
13166        if (!app.persistent || app.isolated) {
13167            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13168                    "Removing non-persistent process during cleanup: " + app);
13169            mProcessNames.remove(app.processName, app.uid);
13170            mIsolatedProcesses.remove(app.uid);
13171            if (mHeavyWeightProcess == app) {
13172                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13173                        mHeavyWeightProcess.userId, 0));
13174                mHeavyWeightProcess = null;
13175            }
13176        } else if (!app.removed) {
13177            // This app is persistent, so we need to keep its record around.
13178            // If it is not already on the pending app list, add it there
13179            // and start a new process for it.
13180            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13181                mPersistentStartingProcesses.add(app);
13182                restart = true;
13183            }
13184        }
13185        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13186                "Clean-up removing on hold: " + app);
13187        mProcessesOnHold.remove(app);
13188
13189        if (app == mHomeProcess) {
13190            mHomeProcess = null;
13191        }
13192        if (app == mPreviousProcess) {
13193            mPreviousProcess = null;
13194        }
13195
13196        if (restart && !app.isolated) {
13197            // We have components that still need to be running in the
13198            // process, so re-launch it.
13199            mProcessNames.put(app.processName, app.uid, app);
13200            startProcessLocked(app, "restart", app.processName, null /* ABI override */);
13201        } else if (app.pid > 0 && app.pid != MY_PID) {
13202            // Goodbye!
13203            boolean removed;
13204            synchronized (mPidsSelfLocked) {
13205                mPidsSelfLocked.remove(app.pid);
13206                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13207            }
13208            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
13209                    app.processName, app.info.uid);
13210            if (app.isolated) {
13211                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13212            }
13213            app.setPid(0);
13214        }
13215    }
13216
13217    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13218        // Look through the content providers we are waiting to have launched,
13219        // and if any run in this process then either schedule a restart of
13220        // the process or kill the client waiting for it if this process has
13221        // gone bad.
13222        int NL = mLaunchingProviders.size();
13223        boolean restart = false;
13224        for (int i=0; i<NL; i++) {
13225            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13226            if (cpr.launchingApp == app) {
13227                if (!alwaysBad && !app.bad) {
13228                    restart = true;
13229                } else {
13230                    removeDyingProviderLocked(app, cpr, true);
13231                    // cpr should have been removed from mLaunchingProviders
13232                    NL = mLaunchingProviders.size();
13233                    i--;
13234                }
13235            }
13236        }
13237        return restart;
13238    }
13239
13240    // =========================================================
13241    // SERVICES
13242    // =========================================================
13243
13244    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13245            int flags) {
13246        enforceNotIsolatedCaller("getServices");
13247        synchronized (this) {
13248            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13249        }
13250    }
13251
13252    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13253        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13254        synchronized (this) {
13255            return mServices.getRunningServiceControlPanelLocked(name);
13256        }
13257    }
13258
13259    public ComponentName startService(IApplicationThread caller, Intent service,
13260            String resolvedType, int userId) {
13261        enforceNotIsolatedCaller("startService");
13262        // Refuse possible leaked file descriptors
13263        if (service != null && service.hasFileDescriptors() == true) {
13264            throw new IllegalArgumentException("File descriptors passed in Intent");
13265        }
13266
13267        if (DEBUG_SERVICE)
13268            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13269        synchronized(this) {
13270            final int callingPid = Binder.getCallingPid();
13271            final int callingUid = Binder.getCallingUid();
13272            final long origId = Binder.clearCallingIdentity();
13273            ComponentName res = mServices.startServiceLocked(caller, service,
13274                    resolvedType, callingPid, callingUid, userId);
13275            Binder.restoreCallingIdentity(origId);
13276            return res;
13277        }
13278    }
13279
13280    ComponentName startServiceInPackage(int uid,
13281            Intent service, String resolvedType, int userId) {
13282        synchronized(this) {
13283            if (DEBUG_SERVICE)
13284                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13285            final long origId = Binder.clearCallingIdentity();
13286            ComponentName res = mServices.startServiceLocked(null, service,
13287                    resolvedType, -1, uid, userId);
13288            Binder.restoreCallingIdentity(origId);
13289            return res;
13290        }
13291    }
13292
13293    public int stopService(IApplicationThread caller, Intent service,
13294            String resolvedType, int userId) {
13295        enforceNotIsolatedCaller("stopService");
13296        // Refuse possible leaked file descriptors
13297        if (service != null && service.hasFileDescriptors() == true) {
13298            throw new IllegalArgumentException("File descriptors passed in Intent");
13299        }
13300
13301        synchronized(this) {
13302            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13303        }
13304    }
13305
13306    public IBinder peekService(Intent service, String resolvedType) {
13307        enforceNotIsolatedCaller("peekService");
13308        // Refuse possible leaked file descriptors
13309        if (service != null && service.hasFileDescriptors() == true) {
13310            throw new IllegalArgumentException("File descriptors passed in Intent");
13311        }
13312        synchronized(this) {
13313            return mServices.peekServiceLocked(service, resolvedType);
13314        }
13315    }
13316
13317    public boolean stopServiceToken(ComponentName className, IBinder token,
13318            int startId) {
13319        synchronized(this) {
13320            return mServices.stopServiceTokenLocked(className, token, startId);
13321        }
13322    }
13323
13324    public void setServiceForeground(ComponentName className, IBinder token,
13325            int id, Notification notification, boolean removeNotification) {
13326        synchronized(this) {
13327            mServices.setServiceForegroundLocked(className, token, id, notification,
13328                    removeNotification);
13329        }
13330    }
13331
13332    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13333            boolean requireFull, String name, String callerPackage) {
13334        final int callingUserId = UserHandle.getUserId(callingUid);
13335        if (callingUserId != userId) {
13336            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13337                if ((requireFull || checkComponentPermission(
13338                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13339                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
13340                        && checkComponentPermission(INTERACT_ACROSS_USERS_FULL,
13341                                callingPid, callingUid, -1, true)
13342                                != PackageManager.PERMISSION_GRANTED) {
13343                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13344                        // In this case, they would like to just execute as their
13345                        // owner user instead of failing.
13346                        userId = callingUserId;
13347                    } else {
13348                        StringBuilder builder = new StringBuilder(128);
13349                        builder.append("Permission Denial: ");
13350                        builder.append(name);
13351                        if (callerPackage != null) {
13352                            builder.append(" from ");
13353                            builder.append(callerPackage);
13354                        }
13355                        builder.append(" asks to run as user ");
13356                        builder.append(userId);
13357                        builder.append(" but is calling from user ");
13358                        builder.append(UserHandle.getUserId(callingUid));
13359                        builder.append("; this requires ");
13360                        builder.append(INTERACT_ACROSS_USERS_FULL);
13361                        if (!requireFull) {
13362                            builder.append(" or ");
13363                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
13364                        }
13365                        String msg = builder.toString();
13366                        Slog.w(TAG, msg);
13367                        throw new SecurityException(msg);
13368                    }
13369                }
13370            }
13371            if (userId == UserHandle.USER_CURRENT
13372                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
13373                // Note that we may be accessing this outside of a lock...
13374                // shouldn't be a big deal, if this is being called outside
13375                // of a locked context there is intrinsically a race with
13376                // the value the caller will receive and someone else changing it.
13377                userId = mCurrentUserId;
13378            }
13379            if (!allowAll && userId < 0) {
13380                throw new IllegalArgumentException(
13381                        "Call does not support special user #" + userId);
13382            }
13383        }
13384        return userId;
13385    }
13386
13387    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13388            String className, int flags) {
13389        boolean result = false;
13390        // For apps that don't have pre-defined UIDs, check for permission
13391        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13392            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13393                if (ActivityManager.checkUidPermission(
13394                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13395                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13396                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13397                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13398                            + " requests FLAG_SINGLE_USER, but app does not hold "
13399                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
13400                    Slog.w(TAG, msg);
13401                    throw new SecurityException(msg);
13402                }
13403                // Permission passed
13404                result = true;
13405            }
13406        } else if ("system".equals(componentProcessName)) {
13407            result = true;
13408        } else {
13409            // App with pre-defined UID, check if it's a persistent app
13410            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13411        }
13412        if (DEBUG_MU) {
13413            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13414                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13415        }
13416        return result;
13417    }
13418
13419    /**
13420     * Checks to see if the caller is in the same app as the singleton
13421     * component, or the component is in a special app. It allows special apps
13422     * to export singleton components but prevents exporting singleton
13423     * components for regular apps.
13424     */
13425    boolean isValidSingletonCall(int callingUid, int componentUid) {
13426        int componentAppId = UserHandle.getAppId(componentUid);
13427        return UserHandle.isSameApp(callingUid, componentUid)
13428                || componentAppId == Process.SYSTEM_UID
13429                || componentAppId == Process.PHONE_UID
13430                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13431                        == PackageManager.PERMISSION_GRANTED;
13432    }
13433
13434    public int bindService(IApplicationThread caller, IBinder token,
13435            Intent service, String resolvedType,
13436            IServiceConnection connection, int flags, int userId) {
13437        enforceNotIsolatedCaller("bindService");
13438        // Refuse possible leaked file descriptors
13439        if (service != null && service.hasFileDescriptors() == true) {
13440            throw new IllegalArgumentException("File descriptors passed in Intent");
13441        }
13442
13443        synchronized(this) {
13444            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13445                    connection, flags, userId);
13446        }
13447    }
13448
13449    public boolean unbindService(IServiceConnection connection) {
13450        synchronized (this) {
13451            return mServices.unbindServiceLocked(connection);
13452        }
13453    }
13454
13455    public void publishService(IBinder token, Intent intent, IBinder service) {
13456        // Refuse possible leaked file descriptors
13457        if (intent != null && intent.hasFileDescriptors() == true) {
13458            throw new IllegalArgumentException("File descriptors passed in Intent");
13459        }
13460
13461        synchronized(this) {
13462            if (!(token instanceof ServiceRecord)) {
13463                throw new IllegalArgumentException("Invalid service token");
13464            }
13465            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13466        }
13467    }
13468
13469    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13470        // Refuse possible leaked file descriptors
13471        if (intent != null && intent.hasFileDescriptors() == true) {
13472            throw new IllegalArgumentException("File descriptors passed in Intent");
13473        }
13474
13475        synchronized(this) {
13476            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13477        }
13478    }
13479
13480    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13481        synchronized(this) {
13482            if (!(token instanceof ServiceRecord)) {
13483                throw new IllegalArgumentException("Invalid service token");
13484            }
13485            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13486        }
13487    }
13488
13489    // =========================================================
13490    // BACKUP AND RESTORE
13491    // =========================================================
13492
13493    // Cause the target app to be launched if necessary and its backup agent
13494    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13495    // activity manager to announce its creation.
13496    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13497        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13498        enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
13499
13500        synchronized(this) {
13501            // !!! TODO: currently no check here that we're already bound
13502            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13503            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13504            synchronized (stats) {
13505                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13506            }
13507
13508            // Backup agent is now in use, its package can't be stopped.
13509            try {
13510                AppGlobals.getPackageManager().setPackageStoppedState(
13511                        app.packageName, false, UserHandle.getUserId(app.uid));
13512            } catch (RemoteException e) {
13513            } catch (IllegalArgumentException e) {
13514                Slog.w(TAG, "Failed trying to unstop package "
13515                        + app.packageName + ": " + e);
13516            }
13517
13518            BackupRecord r = new BackupRecord(ss, app, backupMode);
13519            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13520                    ? new ComponentName(app.packageName, app.backupAgentName)
13521                    : new ComponentName("android", "FullBackupAgent");
13522            // startProcessLocked() returns existing proc's record if it's already running
13523            ProcessRecord proc = startProcessLocked(app.processName, app,
13524                    false, 0, "backup", hostingName, false, false, false);
13525            if (proc == null) {
13526                Slog.e(TAG, "Unable to start backup agent process " + r);
13527                return false;
13528            }
13529
13530            r.app = proc;
13531            mBackupTarget = r;
13532            mBackupAppName = app.packageName;
13533
13534            // Try not to kill the process during backup
13535            updateOomAdjLocked(proc);
13536
13537            // If the process is already attached, schedule the creation of the backup agent now.
13538            // If it is not yet live, this will be done when it attaches to the framework.
13539            if (proc.thread != null) {
13540                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13541                try {
13542                    proc.thread.scheduleCreateBackupAgent(app,
13543                            compatibilityInfoForPackageLocked(app), backupMode);
13544                } catch (RemoteException e) {
13545                    // Will time out on the backup manager side
13546                }
13547            } else {
13548                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13549            }
13550            // Invariants: at this point, the target app process exists and the application
13551            // is either already running or in the process of coming up.  mBackupTarget and
13552            // mBackupAppName describe the app, so that when it binds back to the AM we
13553            // know that it's scheduled for a backup-agent operation.
13554        }
13555
13556        return true;
13557    }
13558
13559    @Override
13560    public void clearPendingBackup() {
13561        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13562        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13563
13564        synchronized (this) {
13565            mBackupTarget = null;
13566            mBackupAppName = null;
13567        }
13568    }
13569
13570    // A backup agent has just come up
13571    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13572        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13573                + " = " + agent);
13574
13575        synchronized(this) {
13576            if (!agentPackageName.equals(mBackupAppName)) {
13577                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13578                return;
13579            }
13580        }
13581
13582        long oldIdent = Binder.clearCallingIdentity();
13583        try {
13584            IBackupManager bm = IBackupManager.Stub.asInterface(
13585                    ServiceManager.getService(Context.BACKUP_SERVICE));
13586            bm.agentConnected(agentPackageName, agent);
13587        } catch (RemoteException e) {
13588            // can't happen; the backup manager service is local
13589        } catch (Exception e) {
13590            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13591            e.printStackTrace();
13592        } finally {
13593            Binder.restoreCallingIdentity(oldIdent);
13594        }
13595    }
13596
13597    // done with this agent
13598    public void unbindBackupAgent(ApplicationInfo appInfo) {
13599        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13600        if (appInfo == null) {
13601            Slog.w(TAG, "unbind backup agent for null app");
13602            return;
13603        }
13604
13605        synchronized(this) {
13606            try {
13607                if (mBackupAppName == null) {
13608                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13609                    return;
13610                }
13611
13612                if (!mBackupAppName.equals(appInfo.packageName)) {
13613                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13614                    return;
13615                }
13616
13617                // Not backing this app up any more; reset its OOM adjustment
13618                final ProcessRecord proc = mBackupTarget.app;
13619                updateOomAdjLocked(proc);
13620
13621                // If the app crashed during backup, 'thread' will be null here
13622                if (proc.thread != null) {
13623                    try {
13624                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13625                                compatibilityInfoForPackageLocked(appInfo));
13626                    } catch (Exception e) {
13627                        Slog.e(TAG, "Exception when unbinding backup agent:");
13628                        e.printStackTrace();
13629                    }
13630                }
13631            } finally {
13632                mBackupTarget = null;
13633                mBackupAppName = null;
13634            }
13635        }
13636    }
13637    // =========================================================
13638    // BROADCASTS
13639    // =========================================================
13640
13641    private final List getStickiesLocked(String action, IntentFilter filter,
13642            List cur, int userId) {
13643        final ContentResolver resolver = mContext.getContentResolver();
13644        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13645        if (stickies == null) {
13646            return cur;
13647        }
13648        final ArrayList<Intent> list = stickies.get(action);
13649        if (list == null) {
13650            return cur;
13651        }
13652        int N = list.size();
13653        for (int i=0; i<N; i++) {
13654            Intent intent = list.get(i);
13655            if (filter.match(resolver, intent, true, TAG) >= 0) {
13656                if (cur == null) {
13657                    cur = new ArrayList<Intent>();
13658                }
13659                cur.add(intent);
13660            }
13661        }
13662        return cur;
13663    }
13664
13665    boolean isPendingBroadcastProcessLocked(int pid) {
13666        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13667                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13668    }
13669
13670    void skipPendingBroadcastLocked(int pid) {
13671            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13672            for (BroadcastQueue queue : mBroadcastQueues) {
13673                queue.skipPendingBroadcastLocked(pid);
13674            }
13675    }
13676
13677    // The app just attached; send any pending broadcasts that it should receive
13678    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13679        boolean didSomething = false;
13680        for (BroadcastQueue queue : mBroadcastQueues) {
13681            didSomething |= queue.sendPendingBroadcastsLocked(app);
13682        }
13683        return didSomething;
13684    }
13685
13686    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13687            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13688        enforceNotIsolatedCaller("registerReceiver");
13689        int callingUid;
13690        int callingPid;
13691        synchronized(this) {
13692            ProcessRecord callerApp = null;
13693            if (caller != null) {
13694                callerApp = getRecordForAppLocked(caller);
13695                if (callerApp == null) {
13696                    throw new SecurityException(
13697                            "Unable to find app for caller " + caller
13698                            + " (pid=" + Binder.getCallingPid()
13699                            + ") when registering receiver " + receiver);
13700                }
13701                if (callerApp.info.uid != Process.SYSTEM_UID &&
13702                        !callerApp.pkgList.containsKey(callerPackage) &&
13703                        !"android".equals(callerPackage)) {
13704                    throw new SecurityException("Given caller package " + callerPackage
13705                            + " is not running in process " + callerApp);
13706                }
13707                callingUid = callerApp.info.uid;
13708                callingPid = callerApp.pid;
13709            } else {
13710                callerPackage = null;
13711                callingUid = Binder.getCallingUid();
13712                callingPid = Binder.getCallingPid();
13713            }
13714
13715            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13716                    true, true, "registerReceiver", callerPackage);
13717
13718            List allSticky = null;
13719
13720            // Look for any matching sticky broadcasts...
13721            Iterator actions = filter.actionsIterator();
13722            if (actions != null) {
13723                while (actions.hasNext()) {
13724                    String action = (String)actions.next();
13725                    allSticky = getStickiesLocked(action, filter, allSticky,
13726                            UserHandle.USER_ALL);
13727                    allSticky = getStickiesLocked(action, filter, allSticky,
13728                            UserHandle.getUserId(callingUid));
13729                }
13730            } else {
13731                allSticky = getStickiesLocked(null, filter, allSticky,
13732                        UserHandle.USER_ALL);
13733                allSticky = getStickiesLocked(null, filter, allSticky,
13734                        UserHandle.getUserId(callingUid));
13735            }
13736
13737            // The first sticky in the list is returned directly back to
13738            // the client.
13739            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13740
13741            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13742                    + ": " + sticky);
13743
13744            if (receiver == null) {
13745                return sticky;
13746            }
13747
13748            ReceiverList rl
13749                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13750            if (rl == null) {
13751                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13752                        userId, receiver);
13753                if (rl.app != null) {
13754                    rl.app.receivers.add(rl);
13755                } else {
13756                    try {
13757                        receiver.asBinder().linkToDeath(rl, 0);
13758                    } catch (RemoteException e) {
13759                        return sticky;
13760                    }
13761                    rl.linkedToDeath = true;
13762                }
13763                mRegisteredReceivers.put(receiver.asBinder(), rl);
13764            } else if (rl.uid != callingUid) {
13765                throw new IllegalArgumentException(
13766                        "Receiver requested to register for uid " + callingUid
13767                        + " was previously registered for uid " + rl.uid);
13768            } else if (rl.pid != callingPid) {
13769                throw new IllegalArgumentException(
13770                        "Receiver requested to register for pid " + callingPid
13771                        + " was previously registered for pid " + rl.pid);
13772            } else if (rl.userId != userId) {
13773                throw new IllegalArgumentException(
13774                        "Receiver requested to register for user " + userId
13775                        + " was previously registered for user " + rl.userId);
13776            }
13777            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13778                    permission, callingUid, userId);
13779            rl.add(bf);
13780            if (!bf.debugCheck()) {
13781                Slog.w(TAG, "==> For Dynamic broadast");
13782            }
13783            mReceiverResolver.addFilter(bf);
13784
13785            // Enqueue broadcasts for all existing stickies that match
13786            // this filter.
13787            if (allSticky != null) {
13788                ArrayList receivers = new ArrayList();
13789                receivers.add(bf);
13790
13791                int N = allSticky.size();
13792                for (int i=0; i<N; i++) {
13793                    Intent intent = (Intent)allSticky.get(i);
13794                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13795                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13796                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13797                            null, null, false, true, true, -1);
13798                    queue.enqueueParallelBroadcastLocked(r);
13799                    queue.scheduleBroadcastsLocked();
13800                }
13801            }
13802
13803            return sticky;
13804        }
13805    }
13806
13807    public void unregisterReceiver(IIntentReceiver receiver) {
13808        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13809
13810        final long origId = Binder.clearCallingIdentity();
13811        try {
13812            boolean doTrim = false;
13813
13814            synchronized(this) {
13815                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13816                if (rl != null) {
13817                    if (rl.curBroadcast != null) {
13818                        BroadcastRecord r = rl.curBroadcast;
13819                        final boolean doNext = finishReceiverLocked(
13820                                receiver.asBinder(), r.resultCode, r.resultData,
13821                                r.resultExtras, r.resultAbort);
13822                        if (doNext) {
13823                            doTrim = true;
13824                            r.queue.processNextBroadcast(false);
13825                        }
13826                    }
13827
13828                    if (rl.app != null) {
13829                        rl.app.receivers.remove(rl);
13830                    }
13831                    removeReceiverLocked(rl);
13832                    if (rl.linkedToDeath) {
13833                        rl.linkedToDeath = false;
13834                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13835                    }
13836                }
13837            }
13838
13839            // If we actually concluded any broadcasts, we might now be able
13840            // to trim the recipients' apps from our working set
13841            if (doTrim) {
13842                trimApplications();
13843                return;
13844            }
13845
13846        } finally {
13847            Binder.restoreCallingIdentity(origId);
13848        }
13849    }
13850
13851    void removeReceiverLocked(ReceiverList rl) {
13852        mRegisteredReceivers.remove(rl.receiver.asBinder());
13853        int N = rl.size();
13854        for (int i=0; i<N; i++) {
13855            mReceiverResolver.removeFilter(rl.get(i));
13856        }
13857    }
13858
13859    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13860        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13861            ProcessRecord r = mLruProcesses.get(i);
13862            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13863                try {
13864                    r.thread.dispatchPackageBroadcast(cmd, packages);
13865                } catch (RemoteException ex) {
13866                }
13867            }
13868        }
13869    }
13870
13871    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13872            int[] users) {
13873        List<ResolveInfo> receivers = null;
13874        try {
13875            HashSet<ComponentName> singleUserReceivers = null;
13876            boolean scannedFirstReceivers = false;
13877            for (int user : users) {
13878                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13879                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13880                if (user != 0 && newReceivers != null) {
13881                    // If this is not the primary user, we need to check for
13882                    // any receivers that should be filtered out.
13883                    for (int i=0; i<newReceivers.size(); i++) {
13884                        ResolveInfo ri = newReceivers.get(i);
13885                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13886                            newReceivers.remove(i);
13887                            i--;
13888                        }
13889                    }
13890                }
13891                if (newReceivers != null && newReceivers.size() == 0) {
13892                    newReceivers = null;
13893                }
13894                if (receivers == null) {
13895                    receivers = newReceivers;
13896                } else if (newReceivers != null) {
13897                    // We need to concatenate the additional receivers
13898                    // found with what we have do far.  This would be easy,
13899                    // but we also need to de-dup any receivers that are
13900                    // singleUser.
13901                    if (!scannedFirstReceivers) {
13902                        // Collect any single user receivers we had already retrieved.
13903                        scannedFirstReceivers = true;
13904                        for (int i=0; i<receivers.size(); i++) {
13905                            ResolveInfo ri = receivers.get(i);
13906                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13907                                ComponentName cn = new ComponentName(
13908                                        ri.activityInfo.packageName, ri.activityInfo.name);
13909                                if (singleUserReceivers == null) {
13910                                    singleUserReceivers = new HashSet<ComponentName>();
13911                                }
13912                                singleUserReceivers.add(cn);
13913                            }
13914                        }
13915                    }
13916                    // Add the new results to the existing results, tracking
13917                    // and de-dupping single user receivers.
13918                    for (int i=0; i<newReceivers.size(); i++) {
13919                        ResolveInfo ri = newReceivers.get(i);
13920                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13921                            ComponentName cn = new ComponentName(
13922                                    ri.activityInfo.packageName, ri.activityInfo.name);
13923                            if (singleUserReceivers == null) {
13924                                singleUserReceivers = new HashSet<ComponentName>();
13925                            }
13926                            if (!singleUserReceivers.contains(cn)) {
13927                                singleUserReceivers.add(cn);
13928                                receivers.add(ri);
13929                            }
13930                        } else {
13931                            receivers.add(ri);
13932                        }
13933                    }
13934                }
13935            }
13936        } catch (RemoteException ex) {
13937            // pm is in same process, this will never happen.
13938        }
13939        return receivers;
13940    }
13941
13942    private final int broadcastIntentLocked(ProcessRecord callerApp,
13943            String callerPackage, Intent intent, String resolvedType,
13944            IIntentReceiver resultTo, int resultCode, String resultData,
13945            Bundle map, String requiredPermission, int appOp,
13946            boolean ordered, boolean sticky, int callingPid, int callingUid,
13947            int userId) {
13948        intent = new Intent(intent);
13949
13950        // By default broadcasts do not go to stopped apps.
13951        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13952
13953        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13954            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13955            + " ordered=" + ordered + " userid=" + userId);
13956        if ((resultTo != null) && !ordered) {
13957            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13958        }
13959
13960        userId = handleIncomingUser(callingPid, callingUid, userId,
13961                true, false, "broadcast", callerPackage);
13962
13963        // Make sure that the user who is receiving this broadcast is started.
13964        // If not, we will just skip it.
13965        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13966            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13967                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13968                Slog.w(TAG, "Skipping broadcast of " + intent
13969                        + ": user " + userId + " is stopped");
13970                return ActivityManager.BROADCAST_SUCCESS;
13971            }
13972        }
13973
13974        /*
13975         * Prevent non-system code (defined here to be non-persistent
13976         * processes) from sending protected broadcasts.
13977         */
13978        int callingAppId = UserHandle.getAppId(callingUid);
13979        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13980                || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
13981                || callingUid == 0) {
13982            // Always okay.
13983        } else if (callerApp == null || !callerApp.persistent) {
13984            try {
13985                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13986                        intent.getAction())) {
13987                    String msg = "Permission Denial: not allowed to send broadcast "
13988                            + intent.getAction() + " from pid="
13989                            + callingPid + ", uid=" + callingUid;
13990                    Slog.w(TAG, msg);
13991                    throw new SecurityException(msg);
13992                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13993                    // Special case for compatibility: we don't want apps to send this,
13994                    // but historically it has not been protected and apps may be using it
13995                    // to poke their own app widget.  So, instead of making it protected,
13996                    // just limit it to the caller.
13997                    if (callerApp == null) {
13998                        String msg = "Permission Denial: not allowed to send broadcast "
13999                                + intent.getAction() + " from unknown caller.";
14000                        Slog.w(TAG, msg);
14001                        throw new SecurityException(msg);
14002                    } else if (intent.getComponent() != null) {
14003                        // They are good enough to send to an explicit component...  verify
14004                        // it is being sent to the calling app.
14005                        if (!intent.getComponent().getPackageName().equals(
14006                                callerApp.info.packageName)) {
14007                            String msg = "Permission Denial: not allowed to send broadcast "
14008                                    + intent.getAction() + " to "
14009                                    + intent.getComponent().getPackageName() + " from "
14010                                    + callerApp.info.packageName;
14011                            Slog.w(TAG, msg);
14012                            throw new SecurityException(msg);
14013                        }
14014                    } else {
14015                        // Limit broadcast to their own package.
14016                        intent.setPackage(callerApp.info.packageName);
14017                    }
14018                }
14019            } catch (RemoteException e) {
14020                Slog.w(TAG, "Remote exception", e);
14021                return ActivityManager.BROADCAST_SUCCESS;
14022            }
14023        }
14024
14025        // Handle special intents: if this broadcast is from the package
14026        // manager about a package being removed, we need to remove all of
14027        // its activities from the history stack.
14028        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14029                intent.getAction());
14030        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14031                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14032                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14033                || uidRemoved) {
14034            if (checkComponentPermission(
14035                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14036                    callingPid, callingUid, -1, true)
14037                    == PackageManager.PERMISSION_GRANTED) {
14038                if (uidRemoved) {
14039                    final Bundle intentExtras = intent.getExtras();
14040                    final int uid = intentExtras != null
14041                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14042                    if (uid >= 0) {
14043                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14044                        synchronized (bs) {
14045                            bs.removeUidStatsLocked(uid);
14046                        }
14047                        mAppOpsService.uidRemoved(uid);
14048                    }
14049                } else {
14050                    // If resources are unavailable just force stop all
14051                    // those packages and flush the attribute cache as well.
14052                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14053                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14054                        if (list != null && (list.length > 0)) {
14055                            for (String pkg : list) {
14056                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14057                                        "storage unmount");
14058                            }
14059                            sendPackageBroadcastLocked(
14060                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14061                        }
14062                    } else {
14063                        Uri data = intent.getData();
14064                        String ssp;
14065                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14066                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14067                                    intent.getAction());
14068                            boolean fullUninstall = removed &&
14069                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14070                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14071                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14072                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14073                                        false, fullUninstall, userId,
14074                                        removed ? "pkg removed" : "pkg changed");
14075                            }
14076                            if (removed) {
14077                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14078                                        new String[] {ssp}, userId);
14079                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14080                                    mAppOpsService.packageRemoved(
14081                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14082
14083                                    // Remove all permissions granted from/to this package
14084                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14085                                }
14086                            }
14087                        }
14088                    }
14089                }
14090            } else {
14091                String msg = "Permission Denial: " + intent.getAction()
14092                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14093                        + ", uid=" + callingUid + ")"
14094                        + " requires "
14095                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14096                Slog.w(TAG, msg);
14097                throw new SecurityException(msg);
14098            }
14099
14100        // Special case for adding a package: by default turn on compatibility
14101        // mode.
14102        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14103            Uri data = intent.getData();
14104            String ssp;
14105            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14106                mCompatModePackages.handlePackageAddedLocked(ssp,
14107                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14108            }
14109        }
14110
14111        /*
14112         * If this is the time zone changed action, queue up a message that will reset the timezone
14113         * of all currently running processes. This message will get queued up before the broadcast
14114         * happens.
14115         */
14116        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14117            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14118        }
14119
14120        /*
14121         * If the user set the time, let all running processes know.
14122         */
14123        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14124            final int is24Hour = intent.getBooleanExtra(
14125                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14126            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14127        }
14128
14129        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14130            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14131        }
14132
14133        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14134            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14135            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14136        }
14137
14138        // Add to the sticky list if requested.
14139        if (sticky) {
14140            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14141                    callingPid, callingUid)
14142                    != PackageManager.PERMISSION_GRANTED) {
14143                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14144                        + callingPid + ", uid=" + callingUid
14145                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14146                Slog.w(TAG, msg);
14147                throw new SecurityException(msg);
14148            }
14149            if (requiredPermission != null) {
14150                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14151                        + " and enforce permission " + requiredPermission);
14152                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14153            }
14154            if (intent.getComponent() != null) {
14155                throw new SecurityException(
14156                        "Sticky broadcasts can't target a specific component");
14157            }
14158            // We use userId directly here, since the "all" target is maintained
14159            // as a separate set of sticky broadcasts.
14160            if (userId != UserHandle.USER_ALL) {
14161                // But first, if this is not a broadcast to all users, then
14162                // make sure it doesn't conflict with an existing broadcast to
14163                // all users.
14164                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14165                        UserHandle.USER_ALL);
14166                if (stickies != null) {
14167                    ArrayList<Intent> list = stickies.get(intent.getAction());
14168                    if (list != null) {
14169                        int N = list.size();
14170                        int i;
14171                        for (i=0; i<N; i++) {
14172                            if (intent.filterEquals(list.get(i))) {
14173                                throw new IllegalArgumentException(
14174                                        "Sticky broadcast " + intent + " for user "
14175                                        + userId + " conflicts with existing global broadcast");
14176                            }
14177                        }
14178                    }
14179                }
14180            }
14181            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14182            if (stickies == null) {
14183                stickies = new ArrayMap<String, ArrayList<Intent>>();
14184                mStickyBroadcasts.put(userId, stickies);
14185            }
14186            ArrayList<Intent> list = stickies.get(intent.getAction());
14187            if (list == null) {
14188                list = new ArrayList<Intent>();
14189                stickies.put(intent.getAction(), list);
14190            }
14191            int N = list.size();
14192            int i;
14193            for (i=0; i<N; i++) {
14194                if (intent.filterEquals(list.get(i))) {
14195                    // This sticky already exists, replace it.
14196                    list.set(i, new Intent(intent));
14197                    break;
14198                }
14199            }
14200            if (i >= N) {
14201                list.add(new Intent(intent));
14202            }
14203        }
14204
14205        int[] users;
14206        if (userId == UserHandle.USER_ALL) {
14207            // Caller wants broadcast to go to all started users.
14208            users = mStartedUserArray;
14209        } else {
14210            // Caller wants broadcast to go to one specific user.
14211            users = new int[] {userId};
14212        }
14213
14214        // Figure out who all will receive this broadcast.
14215        List receivers = null;
14216        List<BroadcastFilter> registeredReceivers = null;
14217        // Need to resolve the intent to interested receivers...
14218        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14219                 == 0) {
14220            receivers = collectReceiverComponents(intent, resolvedType, users);
14221        }
14222        if (intent.getComponent() == null) {
14223            registeredReceivers = mReceiverResolver.queryIntent(intent,
14224                    resolvedType, false, userId);
14225        }
14226
14227        final boolean replacePending =
14228                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14229
14230        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14231                + " replacePending=" + replacePending);
14232
14233        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14234        if (!ordered && NR > 0) {
14235            // If we are not serializing this broadcast, then send the
14236            // registered receivers separately so they don't wait for the
14237            // components to be launched.
14238            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14239            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14240                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14241                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14242                    ordered, sticky, false, userId);
14243            if (DEBUG_BROADCAST) Slog.v(
14244                    TAG, "Enqueueing parallel broadcast " + r);
14245            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14246            if (!replaced) {
14247                queue.enqueueParallelBroadcastLocked(r);
14248                queue.scheduleBroadcastsLocked();
14249            }
14250            registeredReceivers = null;
14251            NR = 0;
14252        }
14253
14254        // Merge into one list.
14255        int ir = 0;
14256        if (receivers != null) {
14257            // A special case for PACKAGE_ADDED: do not allow the package
14258            // being added to see this broadcast.  This prevents them from
14259            // using this as a back door to get run as soon as they are
14260            // installed.  Maybe in the future we want to have a special install
14261            // broadcast or such for apps, but we'd like to deliberately make
14262            // this decision.
14263            String skipPackages[] = null;
14264            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14265                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14266                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14267                Uri data = intent.getData();
14268                if (data != null) {
14269                    String pkgName = data.getSchemeSpecificPart();
14270                    if (pkgName != null) {
14271                        skipPackages = new String[] { pkgName };
14272                    }
14273                }
14274            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14275                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14276            }
14277            if (skipPackages != null && (skipPackages.length > 0)) {
14278                for (String skipPackage : skipPackages) {
14279                    if (skipPackage != null) {
14280                        int NT = receivers.size();
14281                        for (int it=0; it<NT; it++) {
14282                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14283                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14284                                receivers.remove(it);
14285                                it--;
14286                                NT--;
14287                            }
14288                        }
14289                    }
14290                }
14291            }
14292
14293            int NT = receivers != null ? receivers.size() : 0;
14294            int it = 0;
14295            ResolveInfo curt = null;
14296            BroadcastFilter curr = null;
14297            while (it < NT && ir < NR) {
14298                if (curt == null) {
14299                    curt = (ResolveInfo)receivers.get(it);
14300                }
14301                if (curr == null) {
14302                    curr = registeredReceivers.get(ir);
14303                }
14304                if (curr.getPriority() >= curt.priority) {
14305                    // Insert this broadcast record into the final list.
14306                    receivers.add(it, curr);
14307                    ir++;
14308                    curr = null;
14309                    it++;
14310                    NT++;
14311                } else {
14312                    // Skip to the next ResolveInfo in the final list.
14313                    it++;
14314                    curt = null;
14315                }
14316            }
14317        }
14318        while (ir < NR) {
14319            if (receivers == null) {
14320                receivers = new ArrayList();
14321            }
14322            receivers.add(registeredReceivers.get(ir));
14323            ir++;
14324        }
14325
14326        if ((receivers != null && receivers.size() > 0)
14327                || resultTo != null) {
14328            BroadcastQueue queue = broadcastQueueForIntent(intent);
14329            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14330                    callerPackage, callingPid, callingUid, resolvedType,
14331                    requiredPermission, appOp, receivers, resultTo, resultCode,
14332                    resultData, map, ordered, sticky, false, userId);
14333            if (DEBUG_BROADCAST) Slog.v(
14334                    TAG, "Enqueueing ordered broadcast " + r
14335                    + ": prev had " + queue.mOrderedBroadcasts.size());
14336            if (DEBUG_BROADCAST) {
14337                int seq = r.intent.getIntExtra("seq", -1);
14338                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14339            }
14340            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14341            if (!replaced) {
14342                queue.enqueueOrderedBroadcastLocked(r);
14343                queue.scheduleBroadcastsLocked();
14344            }
14345        }
14346
14347        return ActivityManager.BROADCAST_SUCCESS;
14348    }
14349
14350    final Intent verifyBroadcastLocked(Intent intent) {
14351        // Refuse possible leaked file descriptors
14352        if (intent != null && intent.hasFileDescriptors() == true) {
14353            throw new IllegalArgumentException("File descriptors passed in Intent");
14354        }
14355
14356        int flags = intent.getFlags();
14357
14358        if (!mProcessesReady) {
14359            // if the caller really truly claims to know what they're doing, go
14360            // ahead and allow the broadcast without launching any receivers
14361            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14362                intent = new Intent(intent);
14363                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14364            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14365                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14366                        + " before boot completion");
14367                throw new IllegalStateException("Cannot broadcast before boot completed");
14368            }
14369        }
14370
14371        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14372            throw new IllegalArgumentException(
14373                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14374        }
14375
14376        return intent;
14377    }
14378
14379    public final int broadcastIntent(IApplicationThread caller,
14380            Intent intent, String resolvedType, IIntentReceiver resultTo,
14381            int resultCode, String resultData, Bundle map,
14382            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14383        enforceNotIsolatedCaller("broadcastIntent");
14384        synchronized(this) {
14385            intent = verifyBroadcastLocked(intent);
14386
14387            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14388            final int callingPid = Binder.getCallingPid();
14389            final int callingUid = Binder.getCallingUid();
14390            final long origId = Binder.clearCallingIdentity();
14391            int res = broadcastIntentLocked(callerApp,
14392                    callerApp != null ? callerApp.info.packageName : null,
14393                    intent, resolvedType, resultTo,
14394                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14395                    callingPid, callingUid, userId);
14396            Binder.restoreCallingIdentity(origId);
14397            return res;
14398        }
14399    }
14400
14401    int broadcastIntentInPackage(String packageName, int uid,
14402            Intent intent, String resolvedType, IIntentReceiver resultTo,
14403            int resultCode, String resultData, Bundle map,
14404            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14405        synchronized(this) {
14406            intent = verifyBroadcastLocked(intent);
14407
14408            final long origId = Binder.clearCallingIdentity();
14409            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14410                    resultTo, resultCode, resultData, map, requiredPermission,
14411                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14412            Binder.restoreCallingIdentity(origId);
14413            return res;
14414        }
14415    }
14416
14417    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14418        // Refuse possible leaked file descriptors
14419        if (intent != null && intent.hasFileDescriptors() == true) {
14420            throw new IllegalArgumentException("File descriptors passed in Intent");
14421        }
14422
14423        userId = handleIncomingUser(Binder.getCallingPid(),
14424                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
14425
14426        synchronized(this) {
14427            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14428                    != PackageManager.PERMISSION_GRANTED) {
14429                String msg = "Permission Denial: unbroadcastIntent() from pid="
14430                        + Binder.getCallingPid()
14431                        + ", uid=" + Binder.getCallingUid()
14432                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14433                Slog.w(TAG, msg);
14434                throw new SecurityException(msg);
14435            }
14436            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14437            if (stickies != null) {
14438                ArrayList<Intent> list = stickies.get(intent.getAction());
14439                if (list != null) {
14440                    int N = list.size();
14441                    int i;
14442                    for (i=0; i<N; i++) {
14443                        if (intent.filterEquals(list.get(i))) {
14444                            list.remove(i);
14445                            break;
14446                        }
14447                    }
14448                    if (list.size() <= 0) {
14449                        stickies.remove(intent.getAction());
14450                    }
14451                }
14452                if (stickies.size() <= 0) {
14453                    mStickyBroadcasts.remove(userId);
14454                }
14455            }
14456        }
14457    }
14458
14459    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14460            String resultData, Bundle resultExtras, boolean resultAbort) {
14461        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14462        if (r == null) {
14463            Slog.w(TAG, "finishReceiver called but not found on queue");
14464            return false;
14465        }
14466
14467        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14468    }
14469
14470    void backgroundServicesFinishedLocked(int userId) {
14471        for (BroadcastQueue queue : mBroadcastQueues) {
14472            queue.backgroundServicesFinishedLocked(userId);
14473        }
14474    }
14475
14476    public void finishReceiver(IBinder who, int resultCode, String resultData,
14477            Bundle resultExtras, boolean resultAbort) {
14478        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14479
14480        // Refuse possible leaked file descriptors
14481        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14482            throw new IllegalArgumentException("File descriptors passed in Bundle");
14483        }
14484
14485        final long origId = Binder.clearCallingIdentity();
14486        try {
14487            boolean doNext = false;
14488            BroadcastRecord r;
14489
14490            synchronized(this) {
14491                r = broadcastRecordForReceiverLocked(who);
14492                if (r != null) {
14493                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14494                        resultData, resultExtras, resultAbort, true);
14495                }
14496            }
14497
14498            if (doNext) {
14499                r.queue.processNextBroadcast(false);
14500            }
14501            trimApplications();
14502        } finally {
14503            Binder.restoreCallingIdentity(origId);
14504        }
14505    }
14506
14507    // =========================================================
14508    // INSTRUMENTATION
14509    // =========================================================
14510
14511    public boolean startInstrumentation(ComponentName className,
14512            String profileFile, int flags, Bundle arguments,
14513            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14514            int userId, String abiOverride) {
14515        enforceNotIsolatedCaller("startInstrumentation");
14516        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14517                userId, false, true, "startInstrumentation", null);
14518        // Refuse possible leaked file descriptors
14519        if (arguments != null && arguments.hasFileDescriptors()) {
14520            throw new IllegalArgumentException("File descriptors passed in Bundle");
14521        }
14522
14523        synchronized(this) {
14524            InstrumentationInfo ii = null;
14525            ApplicationInfo ai = null;
14526            try {
14527                ii = mContext.getPackageManager().getInstrumentationInfo(
14528                    className, STOCK_PM_FLAGS);
14529                ai = AppGlobals.getPackageManager().getApplicationInfo(
14530                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14531            } catch (PackageManager.NameNotFoundException e) {
14532            } catch (RemoteException e) {
14533            }
14534            if (ii == null) {
14535                reportStartInstrumentationFailure(watcher, className,
14536                        "Unable to find instrumentation info for: " + className);
14537                return false;
14538            }
14539            if (ai == null) {
14540                reportStartInstrumentationFailure(watcher, className,
14541                        "Unable to find instrumentation target package: " + ii.targetPackage);
14542                return false;
14543            }
14544
14545            int match = mContext.getPackageManager().checkSignatures(
14546                    ii.targetPackage, ii.packageName);
14547            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14548                String msg = "Permission Denial: starting instrumentation "
14549                        + className + " from pid="
14550                        + Binder.getCallingPid()
14551                        + ", uid=" + Binder.getCallingPid()
14552                        + " not allowed because package " + ii.packageName
14553                        + " does not have a signature matching the target "
14554                        + ii.targetPackage;
14555                reportStartInstrumentationFailure(watcher, className, msg);
14556                throw new SecurityException(msg);
14557            }
14558
14559            final long origId = Binder.clearCallingIdentity();
14560            // Instrumentation can kill and relaunch even persistent processes
14561            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14562                    "start instr");
14563            ProcessRecord app = addAppLocked(ai, false, abiOverride);
14564            app.instrumentationClass = className;
14565            app.instrumentationInfo = ai;
14566            app.instrumentationProfileFile = profileFile;
14567            app.instrumentationArguments = arguments;
14568            app.instrumentationWatcher = watcher;
14569            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14570            app.instrumentationResultClass = className;
14571            Binder.restoreCallingIdentity(origId);
14572        }
14573
14574        return true;
14575    }
14576
14577    /**
14578     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14579     * error to the logs, but if somebody is watching, send the report there too.  This enables
14580     * the "am" command to report errors with more information.
14581     *
14582     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14583     * @param cn The component name of the instrumentation.
14584     * @param report The error report.
14585     */
14586    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14587            ComponentName cn, String report) {
14588        Slog.w(TAG, report);
14589        try {
14590            if (watcher != null) {
14591                Bundle results = new Bundle();
14592                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14593                results.putString("Error", report);
14594                watcher.instrumentationStatus(cn, -1, results);
14595            }
14596        } catch (RemoteException e) {
14597            Slog.w(TAG, e);
14598        }
14599    }
14600
14601    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14602        if (app.instrumentationWatcher != null) {
14603            try {
14604                // NOTE:  IInstrumentationWatcher *must* be oneway here
14605                app.instrumentationWatcher.instrumentationFinished(
14606                    app.instrumentationClass,
14607                    resultCode,
14608                    results);
14609            } catch (RemoteException e) {
14610            }
14611        }
14612        if (app.instrumentationUiAutomationConnection != null) {
14613            try {
14614                app.instrumentationUiAutomationConnection.shutdown();
14615            } catch (RemoteException re) {
14616                /* ignore */
14617            }
14618            // Only a UiAutomation can set this flag and now that
14619            // it is finished we make sure it is reset to its default.
14620            mUserIsMonkey = false;
14621        }
14622        app.instrumentationWatcher = null;
14623        app.instrumentationUiAutomationConnection = null;
14624        app.instrumentationClass = null;
14625        app.instrumentationInfo = null;
14626        app.instrumentationProfileFile = null;
14627        app.instrumentationArguments = null;
14628
14629        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14630                "finished inst");
14631    }
14632
14633    public void finishInstrumentation(IApplicationThread target,
14634            int resultCode, Bundle results) {
14635        int userId = UserHandle.getCallingUserId();
14636        // Refuse possible leaked file descriptors
14637        if (results != null && results.hasFileDescriptors()) {
14638            throw new IllegalArgumentException("File descriptors passed in Intent");
14639        }
14640
14641        synchronized(this) {
14642            ProcessRecord app = getRecordForAppLocked(target);
14643            if (app == null) {
14644                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14645                return;
14646            }
14647            final long origId = Binder.clearCallingIdentity();
14648            finishInstrumentationLocked(app, resultCode, results);
14649            Binder.restoreCallingIdentity(origId);
14650        }
14651    }
14652
14653    // =========================================================
14654    // CONFIGURATION
14655    // =========================================================
14656
14657    public ConfigurationInfo getDeviceConfigurationInfo() {
14658        ConfigurationInfo config = new ConfigurationInfo();
14659        synchronized (this) {
14660            config.reqTouchScreen = mConfiguration.touchscreen;
14661            config.reqKeyboardType = mConfiguration.keyboard;
14662            config.reqNavigation = mConfiguration.navigation;
14663            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14664                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14665                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14666            }
14667            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14668                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14669                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14670            }
14671            config.reqGlEsVersion = GL_ES_VERSION;
14672        }
14673        return config;
14674    }
14675
14676    ActivityStack getFocusedStack() {
14677        return mStackSupervisor.getFocusedStack();
14678    }
14679
14680    public Configuration getConfiguration() {
14681        Configuration ci;
14682        synchronized(this) {
14683            ci = new Configuration(mConfiguration);
14684        }
14685        return ci;
14686    }
14687
14688    public void updatePersistentConfiguration(Configuration values) {
14689        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14690                "updateConfiguration()");
14691        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14692                "updateConfiguration()");
14693        if (values == null) {
14694            throw new NullPointerException("Configuration must not be null");
14695        }
14696
14697        synchronized(this) {
14698            final long origId = Binder.clearCallingIdentity();
14699            updateConfigurationLocked(values, null, true, false);
14700            Binder.restoreCallingIdentity(origId);
14701        }
14702    }
14703
14704    public void updateConfiguration(Configuration values) {
14705        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14706                "updateConfiguration()");
14707
14708        synchronized(this) {
14709            if (values == null && mWindowManager != null) {
14710                // sentinel: fetch the current configuration from the window manager
14711                values = mWindowManager.computeNewConfiguration();
14712            }
14713
14714            if (mWindowManager != null) {
14715                mProcessList.applyDisplaySize(mWindowManager);
14716            }
14717
14718            final long origId = Binder.clearCallingIdentity();
14719            if (values != null) {
14720                Settings.System.clearConfiguration(values);
14721            }
14722            updateConfigurationLocked(values, null, false, false);
14723            Binder.restoreCallingIdentity(origId);
14724        }
14725    }
14726
14727    /**
14728     * Do either or both things: (1) change the current configuration, and (2)
14729     * make sure the given activity is running with the (now) current
14730     * configuration.  Returns true if the activity has been left running, or
14731     * false if <var>starting</var> is being destroyed to match the new
14732     * configuration.
14733     * @param persistent TODO
14734     */
14735    boolean updateConfigurationLocked(Configuration values,
14736            ActivityRecord starting, boolean persistent, boolean initLocale) {
14737        int changes = 0;
14738
14739        if (values != null) {
14740            Configuration newConfig = new Configuration(mConfiguration);
14741            changes = newConfig.updateFrom(values);
14742            if (changes != 0) {
14743                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14744                    Slog.i(TAG, "Updating configuration to: " + values);
14745                }
14746
14747                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14748
14749                if (values.locale != null && !initLocale) {
14750                    saveLocaleLocked(values.locale,
14751                                     !values.locale.equals(mConfiguration.locale),
14752                                     values.userSetLocale);
14753                }
14754
14755                mConfigurationSeq++;
14756                if (mConfigurationSeq <= 0) {
14757                    mConfigurationSeq = 1;
14758                }
14759                newConfig.seq = mConfigurationSeq;
14760                mConfiguration = newConfig;
14761                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14762                mUsageStatsService.noteStartConfig(newConfig);
14763
14764                final Configuration configCopy = new Configuration(mConfiguration);
14765
14766                // TODO: If our config changes, should we auto dismiss any currently
14767                // showing dialogs?
14768                mShowDialogs = shouldShowDialogs(newConfig);
14769
14770                AttributeCache ac = AttributeCache.instance();
14771                if (ac != null) {
14772                    ac.updateConfiguration(configCopy);
14773                }
14774
14775                // Make sure all resources in our process are updated
14776                // right now, so that anyone who is going to retrieve
14777                // resource values after we return will be sure to get
14778                // the new ones.  This is especially important during
14779                // boot, where the first config change needs to guarantee
14780                // all resources have that config before following boot
14781                // code is executed.
14782                mSystemThread.applyConfigurationToResources(configCopy);
14783
14784                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14785                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14786                    msg.obj = new Configuration(configCopy);
14787                    mHandler.sendMessage(msg);
14788                }
14789
14790                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14791                    ProcessRecord app = mLruProcesses.get(i);
14792                    try {
14793                        if (app.thread != null) {
14794                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14795                                    + app.processName + " new config " + mConfiguration);
14796                            app.thread.scheduleConfigurationChanged(configCopy);
14797                        }
14798                    } catch (Exception e) {
14799                    }
14800                }
14801                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14802                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14803                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14804                        | Intent.FLAG_RECEIVER_FOREGROUND);
14805                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14806                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14807                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14808                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14809                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14810                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14811                    broadcastIntentLocked(null, null, intent,
14812                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14813                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14814                }
14815            }
14816        }
14817
14818        boolean kept = true;
14819        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14820        // mainStack is null during startup.
14821        if (mainStack != null) {
14822            if (changes != 0 && starting == null) {
14823                // If the configuration changed, and the caller is not already
14824                // in the process of starting an activity, then find the top
14825                // activity to check if its configuration needs to change.
14826                starting = mainStack.topRunningActivityLocked(null);
14827            }
14828
14829            if (starting != null) {
14830                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14831                // And we need to make sure at this point that all other activities
14832                // are made visible with the correct configuration.
14833                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14834            }
14835        }
14836
14837        if (values != null && mWindowManager != null) {
14838            mWindowManager.setNewConfiguration(mConfiguration);
14839        }
14840
14841        return kept;
14842    }
14843
14844    /**
14845     * Decide based on the configuration whether we should shouw the ANR,
14846     * crash, etc dialogs.  The idea is that if there is no affordnace to
14847     * press the on-screen buttons, we shouldn't show the dialog.
14848     *
14849     * A thought: SystemUI might also want to get told about this, the Power
14850     * dialog / global actions also might want different behaviors.
14851     */
14852    private static final boolean shouldShowDialogs(Configuration config) {
14853        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14854                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14855    }
14856
14857    /**
14858     * Save the locale.  You must be inside a synchronized (this) block.
14859     */
14860    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14861        if(isDiff) {
14862            SystemProperties.set("user.language", l.getLanguage());
14863            SystemProperties.set("user.region", l.getCountry());
14864        }
14865
14866        if(isPersist) {
14867            SystemProperties.set("persist.sys.language", l.getLanguage());
14868            SystemProperties.set("persist.sys.country", l.getCountry());
14869            SystemProperties.set("persist.sys.localevar", l.getVariant());
14870        }
14871    }
14872
14873    @Override
14874    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14875        ActivityRecord srec = ActivityRecord.forToken(token);
14876        return srec != null && srec.task.affinity != null &&
14877                srec.task.affinity.equals(destAffinity);
14878    }
14879
14880    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14881            Intent resultData) {
14882
14883        synchronized (this) {
14884            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14885            if (stack != null) {
14886                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14887            }
14888            return false;
14889        }
14890    }
14891
14892    public int getLaunchedFromUid(IBinder activityToken) {
14893        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14894        if (srec == null) {
14895            return -1;
14896        }
14897        return srec.launchedFromUid;
14898    }
14899
14900    public String getLaunchedFromPackage(IBinder activityToken) {
14901        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14902        if (srec == null) {
14903            return null;
14904        }
14905        return srec.launchedFromPackage;
14906    }
14907
14908    // =========================================================
14909    // LIFETIME MANAGEMENT
14910    // =========================================================
14911
14912    // Returns which broadcast queue the app is the current [or imminent] receiver
14913    // on, or 'null' if the app is not an active broadcast recipient.
14914    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14915        BroadcastRecord r = app.curReceiver;
14916        if (r != null) {
14917            return r.queue;
14918        }
14919
14920        // It's not the current receiver, but it might be starting up to become one
14921        synchronized (this) {
14922            for (BroadcastQueue queue : mBroadcastQueues) {
14923                r = queue.mPendingBroadcast;
14924                if (r != null && r.curApp == app) {
14925                    // found it; report which queue it's in
14926                    return queue;
14927                }
14928            }
14929        }
14930
14931        return null;
14932    }
14933
14934    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14935            boolean doingAll, long now) {
14936        if (mAdjSeq == app.adjSeq) {
14937            // This adjustment has already been computed.
14938            return app.curRawAdj;
14939        }
14940
14941        if (app.thread == null) {
14942            app.adjSeq = mAdjSeq;
14943            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14944            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14945            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14946        }
14947
14948        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14949        app.adjSource = null;
14950        app.adjTarget = null;
14951        app.empty = false;
14952        app.cached = false;
14953
14954        final int activitiesSize = app.activities.size();
14955
14956        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14957            // The max adjustment doesn't allow this app to be anything
14958            // below foreground, so it is not worth doing work for it.
14959            app.adjType = "fixed";
14960            app.adjSeq = mAdjSeq;
14961            app.curRawAdj = app.maxAdj;
14962            app.foregroundActivities = false;
14963            app.keeping = true;
14964            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14965            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14966            // System processes can do UI, and when they do we want to have
14967            // them trim their memory after the user leaves the UI.  To
14968            // facilitate this, here we need to determine whether or not it
14969            // is currently showing UI.
14970            app.systemNoUi = true;
14971            if (app == TOP_APP) {
14972                app.systemNoUi = false;
14973            } else if (activitiesSize > 0) {
14974                for (int j = 0; j < activitiesSize; j++) {
14975                    final ActivityRecord r = app.activities.get(j);
14976                    if (r.visible) {
14977                        app.systemNoUi = false;
14978                    }
14979                }
14980            }
14981            if (!app.systemNoUi) {
14982                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14983            }
14984            return (app.curAdj=app.maxAdj);
14985        }
14986
14987        app.keeping = false;
14988        app.systemNoUi = false;
14989
14990        // Determine the importance of the process, starting with most
14991        // important to least, and assign an appropriate OOM adjustment.
14992        int adj;
14993        int schedGroup;
14994        int procState;
14995        boolean foregroundActivities = false;
14996        boolean interesting = false;
14997        BroadcastQueue queue;
14998        if (app == TOP_APP) {
14999            // The last app on the list is the foreground app.
15000            adj = ProcessList.FOREGROUND_APP_ADJ;
15001            schedGroup = Process.THREAD_GROUP_DEFAULT;
15002            app.adjType = "top-activity";
15003            foregroundActivities = true;
15004            interesting = true;
15005            procState = ActivityManager.PROCESS_STATE_TOP;
15006        } else if (app.instrumentationClass != null) {
15007            // Don't want to kill running instrumentation.
15008            adj = ProcessList.FOREGROUND_APP_ADJ;
15009            schedGroup = Process.THREAD_GROUP_DEFAULT;
15010            app.adjType = "instrumentation";
15011            interesting = true;
15012            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15013        } else if ((queue = isReceivingBroadcast(app)) != null) {
15014            // An app that is currently receiving a broadcast also
15015            // counts as being in the foreground for OOM killer purposes.
15016            // It's placed in a sched group based on the nature of the
15017            // broadcast as reflected by which queue it's active in.
15018            adj = ProcessList.FOREGROUND_APP_ADJ;
15019            schedGroup = (queue == mFgBroadcastQueue)
15020                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15021            app.adjType = "broadcast";
15022            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15023        } else if (app.executingServices.size() > 0) {
15024            // An app that is currently executing a service callback also
15025            // counts as being in the foreground.
15026            adj = ProcessList.FOREGROUND_APP_ADJ;
15027            schedGroup = app.execServicesFg ?
15028                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15029            app.adjType = "exec-service";
15030            procState = ActivityManager.PROCESS_STATE_SERVICE;
15031            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15032        } else {
15033            // As far as we know the process is empty.  We may change our mind later.
15034            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15035            // At this point we don't actually know the adjustment.  Use the cached adj
15036            // value that the caller wants us to.
15037            adj = cachedAdj;
15038            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15039            app.cached = true;
15040            app.empty = true;
15041            app.adjType = "cch-empty";
15042        }
15043
15044        // Examine all activities if not already foreground.
15045        if (!foregroundActivities && activitiesSize > 0) {
15046            for (int j = 0; j < activitiesSize; j++) {
15047                final ActivityRecord r = app.activities.get(j);
15048                if (r.app != app) {
15049                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15050                            + app + "?!?");
15051                    continue;
15052                }
15053                if (r.visible) {
15054                    // App has a visible activity; only upgrade adjustment.
15055                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15056                        adj = ProcessList.VISIBLE_APP_ADJ;
15057                        app.adjType = "visible";
15058                    }
15059                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15060                        procState = ActivityManager.PROCESS_STATE_TOP;
15061                    }
15062                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15063                    app.cached = false;
15064                    app.empty = false;
15065                    foregroundActivities = true;
15066                    break;
15067                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15068                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15069                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15070                        app.adjType = "pausing";
15071                    }
15072                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15073                        procState = ActivityManager.PROCESS_STATE_TOP;
15074                    }
15075                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15076                    app.cached = false;
15077                    app.empty = false;
15078                    foregroundActivities = true;
15079                } else if (r.state == ActivityState.STOPPING) {
15080                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15081                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15082                        app.adjType = "stopping";
15083                    }
15084                    // For the process state, we will at this point consider the
15085                    // process to be cached.  It will be cached either as an activity
15086                    // or empty depending on whether the activity is finishing.  We do
15087                    // this so that we can treat the process as cached for purposes of
15088                    // memory trimming (determing current memory level, trim command to
15089                    // send to process) since there can be an arbitrary number of stopping
15090                    // processes and they should soon all go into the cached state.
15091                    if (!r.finishing) {
15092                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15093                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15094                        }
15095                    }
15096                    app.cached = false;
15097                    app.empty = false;
15098                    foregroundActivities = true;
15099                } else {
15100                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15101                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15102                        app.adjType = "cch-act";
15103                    }
15104                }
15105            }
15106        }
15107
15108        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15109            if (app.foregroundServices) {
15110                // The user is aware of this app, so make it visible.
15111                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15112                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15113                app.cached = false;
15114                app.adjType = "fg-service";
15115                schedGroup = Process.THREAD_GROUP_DEFAULT;
15116            } else if (app.forcingToForeground != null) {
15117                // The user is aware of this app, so make it visible.
15118                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15119                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15120                app.cached = false;
15121                app.adjType = "force-fg";
15122                app.adjSource = app.forcingToForeground;
15123                schedGroup = Process.THREAD_GROUP_DEFAULT;
15124            }
15125        }
15126
15127        if (app.foregroundServices) {
15128            interesting = true;
15129        }
15130
15131        if (app == mHeavyWeightProcess) {
15132            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15133                // We don't want to kill the current heavy-weight process.
15134                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15135                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15136                app.cached = false;
15137                app.adjType = "heavy";
15138            }
15139            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15140                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15141            }
15142        }
15143
15144        if (app == mHomeProcess) {
15145            if (adj > ProcessList.HOME_APP_ADJ) {
15146                // This process is hosting what we currently consider to be the
15147                // home app, so we don't want to let it go into the background.
15148                adj = ProcessList.HOME_APP_ADJ;
15149                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15150                app.cached = false;
15151                app.adjType = "home";
15152            }
15153            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15154                procState = ActivityManager.PROCESS_STATE_HOME;
15155            }
15156        }
15157
15158        if (app == mPreviousProcess && app.activities.size() > 0) {
15159            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15160                // This was the previous process that showed UI to the user.
15161                // We want to try to keep it around more aggressively, to give
15162                // a good experience around switching between two apps.
15163                adj = ProcessList.PREVIOUS_APP_ADJ;
15164                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15165                app.cached = false;
15166                app.adjType = "previous";
15167            }
15168            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15169                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15170            }
15171        }
15172
15173        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15174                + " reason=" + app.adjType);
15175
15176        // By default, we use the computed adjustment.  It may be changed if
15177        // there are applications dependent on our services or providers, but
15178        // this gives us a baseline and makes sure we don't get into an
15179        // infinite recursion.
15180        app.adjSeq = mAdjSeq;
15181        app.curRawAdj = adj;
15182        app.hasStartedServices = false;
15183
15184        if (mBackupTarget != null && app == mBackupTarget.app) {
15185            // If possible we want to avoid killing apps while they're being backed up
15186            if (adj > ProcessList.BACKUP_APP_ADJ) {
15187                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15188                adj = ProcessList.BACKUP_APP_ADJ;
15189                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15190                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15191                }
15192                app.adjType = "backup";
15193                app.cached = false;
15194            }
15195            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15196                procState = ActivityManager.PROCESS_STATE_BACKUP;
15197            }
15198        }
15199
15200        boolean mayBeTop = false;
15201
15202        for (int is = app.services.size()-1;
15203                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15204                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15205                        || procState > ActivityManager.PROCESS_STATE_TOP);
15206                is--) {
15207            ServiceRecord s = app.services.valueAt(is);
15208            if (s.startRequested) {
15209                app.hasStartedServices = true;
15210                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15211                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15212                }
15213                if (app.hasShownUi && app != mHomeProcess) {
15214                    // If this process has shown some UI, let it immediately
15215                    // go to the LRU list because it may be pretty heavy with
15216                    // UI stuff.  We'll tag it with a label just to help
15217                    // debug and understand what is going on.
15218                    if (adj > ProcessList.SERVICE_ADJ) {
15219                        app.adjType = "cch-started-ui-services";
15220                    }
15221                } else {
15222                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15223                        // This service has seen some activity within
15224                        // recent memory, so we will keep its process ahead
15225                        // of the background processes.
15226                        if (adj > ProcessList.SERVICE_ADJ) {
15227                            adj = ProcessList.SERVICE_ADJ;
15228                            app.adjType = "started-services";
15229                            app.cached = false;
15230                        }
15231                    }
15232                    // If we have let the service slide into the background
15233                    // state, still have some text describing what it is doing
15234                    // even though the service no longer has an impact.
15235                    if (adj > ProcessList.SERVICE_ADJ) {
15236                        app.adjType = "cch-started-services";
15237                    }
15238                }
15239                // Don't kill this process because it is doing work; it
15240                // has said it is doing work.
15241                app.keeping = true;
15242            }
15243            for (int conni = s.connections.size()-1;
15244                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15245                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15246                            || procState > ActivityManager.PROCESS_STATE_TOP);
15247                    conni--) {
15248                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15249                for (int i = 0;
15250                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15251                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15252                                || procState > ActivityManager.PROCESS_STATE_TOP);
15253                        i++) {
15254                    // XXX should compute this based on the max of
15255                    // all connected clients.
15256                    ConnectionRecord cr = clist.get(i);
15257                    if (cr.binding.client == app) {
15258                        // Binding to ourself is not interesting.
15259                        continue;
15260                    }
15261                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15262                        ProcessRecord client = cr.binding.client;
15263                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15264                                TOP_APP, doingAll, now);
15265                        int clientProcState = client.curProcState;
15266                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15267                            // If the other app is cached for any reason, for purposes here
15268                            // we are going to consider it empty.  The specific cached state
15269                            // doesn't propagate except under certain conditions.
15270                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15271                        }
15272                        String adjType = null;
15273                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15274                            // Not doing bind OOM management, so treat
15275                            // this guy more like a started service.
15276                            if (app.hasShownUi && app != mHomeProcess) {
15277                                // If this process has shown some UI, let it immediately
15278                                // go to the LRU list because it may be pretty heavy with
15279                                // UI stuff.  We'll tag it with a label just to help
15280                                // debug and understand what is going on.
15281                                if (adj > clientAdj) {
15282                                    adjType = "cch-bound-ui-services";
15283                                }
15284                                app.cached = false;
15285                                clientAdj = adj;
15286                                clientProcState = procState;
15287                            } else {
15288                                if (now >= (s.lastActivity
15289                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15290                                    // This service has not seen activity within
15291                                    // recent memory, so allow it to drop to the
15292                                    // LRU list if there is no other reason to keep
15293                                    // it around.  We'll also tag it with a label just
15294                                    // to help debug and undertand what is going on.
15295                                    if (adj > clientAdj) {
15296                                        adjType = "cch-bound-services";
15297                                    }
15298                                    clientAdj = adj;
15299                                }
15300                            }
15301                        }
15302                        if (adj > clientAdj) {
15303                            // If this process has recently shown UI, and
15304                            // the process that is binding to it is less
15305                            // important than being visible, then we don't
15306                            // care about the binding as much as we care
15307                            // about letting this process get into the LRU
15308                            // list to be killed and restarted if needed for
15309                            // memory.
15310                            if (app.hasShownUi && app != mHomeProcess
15311                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15312                                adjType = "cch-bound-ui-services";
15313                            } else {
15314                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15315                                        |Context.BIND_IMPORTANT)) != 0) {
15316                                    adj = clientAdj;
15317                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15318                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15319                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15320                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15321                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15322                                    adj = clientAdj;
15323                                } else {
15324                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15325                                        adj = ProcessList.VISIBLE_APP_ADJ;
15326                                    }
15327                                }
15328                                if (!client.cached) {
15329                                    app.cached = false;
15330                                }
15331                                if (client.keeping) {
15332                                    app.keeping = true;
15333                                }
15334                                adjType = "service";
15335                            }
15336                        }
15337                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15338                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15339                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15340                            }
15341                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15342                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15343                                    // Special handling of clients who are in the top state.
15344                                    // We *may* want to consider this process to be in the
15345                                    // top state as well, but only if there is not another
15346                                    // reason for it to be running.  Being on the top is a
15347                                    // special state, meaning you are specifically running
15348                                    // for the current top app.  If the process is already
15349                                    // running in the background for some other reason, it
15350                                    // is more important to continue considering it to be
15351                                    // in the background state.
15352                                    mayBeTop = true;
15353                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15354                                } else {
15355                                    // Special handling for above-top states (persistent
15356                                    // processes).  These should not bring the current process
15357                                    // into the top state, since they are not on top.  Instead
15358                                    // give them the best state after that.
15359                                    clientProcState =
15360                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15361                                }
15362                            }
15363                        } else {
15364                            if (clientProcState <
15365                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15366                                clientProcState =
15367                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15368                            }
15369                        }
15370                        if (procState > clientProcState) {
15371                            procState = clientProcState;
15372                        }
15373                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15374                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15375                            app.pendingUiClean = true;
15376                        }
15377                        if (adjType != null) {
15378                            app.adjType = adjType;
15379                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15380                                    .REASON_SERVICE_IN_USE;
15381                            app.adjSource = cr.binding.client;
15382                            app.adjSourceOom = clientAdj;
15383                            app.adjTarget = s.name;
15384                        }
15385                    }
15386                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15387                        app.treatLikeActivity = true;
15388                    }
15389                    final ActivityRecord a = cr.activity;
15390                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15391                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15392                                (a.visible || a.state == ActivityState.RESUMED
15393                                 || a.state == ActivityState.PAUSING)) {
15394                            adj = ProcessList.FOREGROUND_APP_ADJ;
15395                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15396                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15397                            }
15398                            app.cached = false;
15399                            app.adjType = "service";
15400                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15401                                    .REASON_SERVICE_IN_USE;
15402                            app.adjSource = a;
15403                            app.adjSourceOom = adj;
15404                            app.adjTarget = s.name;
15405                        }
15406                    }
15407                }
15408            }
15409        }
15410
15411        for (int provi = app.pubProviders.size()-1;
15412                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15413                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15414                        || procState > ActivityManager.PROCESS_STATE_TOP);
15415                provi--) {
15416            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15417            for (int i = cpr.connections.size()-1;
15418                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15419                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15420                            || procState > ActivityManager.PROCESS_STATE_TOP);
15421                    i--) {
15422                ContentProviderConnection conn = cpr.connections.get(i);
15423                ProcessRecord client = conn.client;
15424                if (client == app) {
15425                    // Being our own client is not interesting.
15426                    continue;
15427                }
15428                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15429                int clientProcState = client.curProcState;
15430                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15431                    // If the other app is cached for any reason, for purposes here
15432                    // we are going to consider it empty.
15433                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15434                }
15435                if (adj > clientAdj) {
15436                    if (app.hasShownUi && app != mHomeProcess
15437                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15438                        app.adjType = "cch-ui-provider";
15439                    } else {
15440                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15441                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15442                        app.adjType = "provider";
15443                    }
15444                    app.cached &= client.cached;
15445                    app.keeping |= client.keeping;
15446                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15447                            .REASON_PROVIDER_IN_USE;
15448                    app.adjSource = client;
15449                    app.adjSourceOom = clientAdj;
15450                    app.adjTarget = cpr.name;
15451                }
15452                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15453                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15454                        // Special handling of clients who are in the top state.
15455                        // We *may* want to consider this process to be in the
15456                        // top state as well, but only if there is not another
15457                        // reason for it to be running.  Being on the top is a
15458                        // special state, meaning you are specifically running
15459                        // for the current top app.  If the process is already
15460                        // running in the background for some other reason, it
15461                        // is more important to continue considering it to be
15462                        // in the background state.
15463                        mayBeTop = true;
15464                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15465                    } else {
15466                        // Special handling for above-top states (persistent
15467                        // processes).  These should not bring the current process
15468                        // into the top state, since they are not on top.  Instead
15469                        // give them the best state after that.
15470                        clientProcState =
15471                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15472                    }
15473                }
15474                if (procState > clientProcState) {
15475                    procState = clientProcState;
15476                }
15477                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15478                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15479                }
15480            }
15481            // If the provider has external (non-framework) process
15482            // dependencies, ensure that its adjustment is at least
15483            // FOREGROUND_APP_ADJ.
15484            if (cpr.hasExternalProcessHandles()) {
15485                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15486                    adj = ProcessList.FOREGROUND_APP_ADJ;
15487                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15488                    app.cached = false;
15489                    app.keeping = true;
15490                    app.adjType = "provider";
15491                    app.adjTarget = cpr.name;
15492                }
15493                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15494                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15495                }
15496            }
15497        }
15498
15499        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15500            // A client of one of our services or providers is in the top state.  We
15501            // *may* want to be in the top state, but not if we are already running in
15502            // the background for some other reason.  For the decision here, we are going
15503            // to pick out a few specific states that we want to remain in when a client
15504            // is top (states that tend to be longer-term) and otherwise allow it to go
15505            // to the top state.
15506            switch (procState) {
15507                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15508                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15509                case ActivityManager.PROCESS_STATE_SERVICE:
15510                    // These all are longer-term states, so pull them up to the top
15511                    // of the background states, but not all the way to the top state.
15512                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15513                    break;
15514                default:
15515                    // Otherwise, top is a better choice, so take it.
15516                    procState = ActivityManager.PROCESS_STATE_TOP;
15517                    break;
15518            }
15519        }
15520
15521        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15522            if (app.hasClientActivities) {
15523                // This is a cached process, but with client activities.  Mark it so.
15524                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15525                app.adjType = "cch-client-act";
15526            } else if (app.treatLikeActivity) {
15527                // This is a cached process, but somebody wants us to treat it like it has
15528                // an activity, okay!
15529                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15530                app.adjType = "cch-as-act";
15531            }
15532        }
15533
15534        if (adj == ProcessList.SERVICE_ADJ) {
15535            if (doingAll) {
15536                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15537                mNewNumServiceProcs++;
15538                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15539                if (!app.serviceb) {
15540                    // This service isn't far enough down on the LRU list to
15541                    // normally be a B service, but if we are low on RAM and it
15542                    // is large we want to force it down since we would prefer to
15543                    // keep launcher over it.
15544                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15545                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15546                        app.serviceHighRam = true;
15547                        app.serviceb = true;
15548                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15549                    } else {
15550                        mNewNumAServiceProcs++;
15551                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15552                    }
15553                } else {
15554                    app.serviceHighRam = false;
15555                }
15556            }
15557            if (app.serviceb) {
15558                adj = ProcessList.SERVICE_B_ADJ;
15559            }
15560        }
15561
15562        app.curRawAdj = adj;
15563
15564        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15565        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15566        if (adj > app.maxAdj) {
15567            adj = app.maxAdj;
15568            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15569                schedGroup = Process.THREAD_GROUP_DEFAULT;
15570            }
15571        }
15572        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15573            app.keeping = true;
15574        }
15575
15576        // Do final modification to adj.  Everything we do between here and applying
15577        // the final setAdj must be done in this function, because we will also use
15578        // it when computing the final cached adj later.  Note that we don't need to
15579        // worry about this for max adj above, since max adj will always be used to
15580        // keep it out of the cached vaues.
15581        app.curAdj = app.modifyRawOomAdj(adj);
15582        app.curSchedGroup = schedGroup;
15583        app.curProcState = procState;
15584        app.foregroundActivities = foregroundActivities;
15585
15586        return app.curRawAdj;
15587    }
15588
15589    /**
15590     * Schedule PSS collection of a process.
15591     */
15592    void requestPssLocked(ProcessRecord proc, int procState) {
15593        if (mPendingPssProcesses.contains(proc)) {
15594            return;
15595        }
15596        if (mPendingPssProcesses.size() == 0) {
15597            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15598        }
15599        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15600        proc.pssProcState = procState;
15601        mPendingPssProcesses.add(proc);
15602    }
15603
15604    /**
15605     * Schedule PSS collection of all processes.
15606     */
15607    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15608        if (!always) {
15609            if (now < (mLastFullPssTime +
15610                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15611                return;
15612            }
15613        }
15614        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15615        mLastFullPssTime = now;
15616        mFullPssPending = true;
15617        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15618        mPendingPssProcesses.clear();
15619        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15620            ProcessRecord app = mLruProcesses.get(i);
15621            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15622                app.pssProcState = app.setProcState;
15623                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15624                        isSleeping(), now);
15625                mPendingPssProcesses.add(app);
15626            }
15627        }
15628        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15629    }
15630
15631    /**
15632     * Ask a given process to GC right now.
15633     */
15634    final void performAppGcLocked(ProcessRecord app) {
15635        try {
15636            app.lastRequestedGc = SystemClock.uptimeMillis();
15637            if (app.thread != null) {
15638                if (app.reportLowMemory) {
15639                    app.reportLowMemory = false;
15640                    app.thread.scheduleLowMemory();
15641                } else {
15642                    app.thread.processInBackground();
15643                }
15644            }
15645        } catch (Exception e) {
15646            // whatever.
15647        }
15648    }
15649
15650    /**
15651     * Returns true if things are idle enough to perform GCs.
15652     */
15653    private final boolean canGcNowLocked() {
15654        boolean processingBroadcasts = false;
15655        for (BroadcastQueue q : mBroadcastQueues) {
15656            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15657                processingBroadcasts = true;
15658            }
15659        }
15660        return !processingBroadcasts
15661                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15662    }
15663
15664    /**
15665     * Perform GCs on all processes that are waiting for it, but only
15666     * if things are idle.
15667     */
15668    final void performAppGcsLocked() {
15669        final int N = mProcessesToGc.size();
15670        if (N <= 0) {
15671            return;
15672        }
15673        if (canGcNowLocked()) {
15674            while (mProcessesToGc.size() > 0) {
15675                ProcessRecord proc = mProcessesToGc.remove(0);
15676                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15677                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15678                            <= SystemClock.uptimeMillis()) {
15679                        // To avoid spamming the system, we will GC processes one
15680                        // at a time, waiting a few seconds between each.
15681                        performAppGcLocked(proc);
15682                        scheduleAppGcsLocked();
15683                        return;
15684                    } else {
15685                        // It hasn't been long enough since we last GCed this
15686                        // process...  put it in the list to wait for its time.
15687                        addProcessToGcListLocked(proc);
15688                        break;
15689                    }
15690                }
15691            }
15692
15693            scheduleAppGcsLocked();
15694        }
15695    }
15696
15697    /**
15698     * If all looks good, perform GCs on all processes waiting for them.
15699     */
15700    final void performAppGcsIfAppropriateLocked() {
15701        if (canGcNowLocked()) {
15702            performAppGcsLocked();
15703            return;
15704        }
15705        // Still not idle, wait some more.
15706        scheduleAppGcsLocked();
15707    }
15708
15709    /**
15710     * Schedule the execution of all pending app GCs.
15711     */
15712    final void scheduleAppGcsLocked() {
15713        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15714
15715        if (mProcessesToGc.size() > 0) {
15716            // Schedule a GC for the time to the next process.
15717            ProcessRecord proc = mProcessesToGc.get(0);
15718            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15719
15720            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15721            long now = SystemClock.uptimeMillis();
15722            if (when < (now+GC_TIMEOUT)) {
15723                when = now + GC_TIMEOUT;
15724            }
15725            mHandler.sendMessageAtTime(msg, when);
15726        }
15727    }
15728
15729    /**
15730     * Add a process to the array of processes waiting to be GCed.  Keeps the
15731     * list in sorted order by the last GC time.  The process can't already be
15732     * on the list.
15733     */
15734    final void addProcessToGcListLocked(ProcessRecord proc) {
15735        boolean added = false;
15736        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15737            if (mProcessesToGc.get(i).lastRequestedGc <
15738                    proc.lastRequestedGc) {
15739                added = true;
15740                mProcessesToGc.add(i+1, proc);
15741                break;
15742            }
15743        }
15744        if (!added) {
15745            mProcessesToGc.add(0, proc);
15746        }
15747    }
15748
15749    /**
15750     * Set up to ask a process to GC itself.  This will either do it
15751     * immediately, or put it on the list of processes to gc the next
15752     * time things are idle.
15753     */
15754    final void scheduleAppGcLocked(ProcessRecord app) {
15755        long now = SystemClock.uptimeMillis();
15756        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15757            return;
15758        }
15759        if (!mProcessesToGc.contains(app)) {
15760            addProcessToGcListLocked(app);
15761            scheduleAppGcsLocked();
15762        }
15763    }
15764
15765    final void checkExcessivePowerUsageLocked(boolean doKills) {
15766        updateCpuStatsNow();
15767
15768        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15769        boolean doWakeKills = doKills;
15770        boolean doCpuKills = doKills;
15771        if (mLastPowerCheckRealtime == 0) {
15772            doWakeKills = false;
15773        }
15774        if (mLastPowerCheckUptime == 0) {
15775            doCpuKills = false;
15776        }
15777        if (stats.isScreenOn()) {
15778            doWakeKills = false;
15779        }
15780        final long curRealtime = SystemClock.elapsedRealtime();
15781        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15782        final long curUptime = SystemClock.uptimeMillis();
15783        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15784        mLastPowerCheckRealtime = curRealtime;
15785        mLastPowerCheckUptime = curUptime;
15786        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15787            doWakeKills = false;
15788        }
15789        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15790            doCpuKills = false;
15791        }
15792        int i = mLruProcesses.size();
15793        while (i > 0) {
15794            i--;
15795            ProcessRecord app = mLruProcesses.get(i);
15796            if (!app.keeping) {
15797                long wtime;
15798                synchronized (stats) {
15799                    wtime = stats.getProcessWakeTime(app.info.uid,
15800                            app.pid, curRealtime);
15801                }
15802                long wtimeUsed = wtime - app.lastWakeTime;
15803                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15804                if (DEBUG_POWER) {
15805                    StringBuilder sb = new StringBuilder(128);
15806                    sb.append("Wake for ");
15807                    app.toShortString(sb);
15808                    sb.append(": over ");
15809                    TimeUtils.formatDuration(realtimeSince, sb);
15810                    sb.append(" used ");
15811                    TimeUtils.formatDuration(wtimeUsed, sb);
15812                    sb.append(" (");
15813                    sb.append((wtimeUsed*100)/realtimeSince);
15814                    sb.append("%)");
15815                    Slog.i(TAG, sb.toString());
15816                    sb.setLength(0);
15817                    sb.append("CPU for ");
15818                    app.toShortString(sb);
15819                    sb.append(": over ");
15820                    TimeUtils.formatDuration(uptimeSince, sb);
15821                    sb.append(" used ");
15822                    TimeUtils.formatDuration(cputimeUsed, sb);
15823                    sb.append(" (");
15824                    sb.append((cputimeUsed*100)/uptimeSince);
15825                    sb.append("%)");
15826                    Slog.i(TAG, sb.toString());
15827                }
15828                // If a process has held a wake lock for more
15829                // than 50% of the time during this period,
15830                // that sounds bad.  Kill!
15831                if (doWakeKills && realtimeSince > 0
15832                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15833                    synchronized (stats) {
15834                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15835                                realtimeSince, wtimeUsed);
15836                    }
15837                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15838                            + " during " + realtimeSince);
15839                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15840                } else if (doCpuKills && uptimeSince > 0
15841                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15842                    synchronized (stats) {
15843                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15844                                uptimeSince, cputimeUsed);
15845                    }
15846                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15847                            + " during " + uptimeSince);
15848                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15849                } else {
15850                    app.lastWakeTime = wtime;
15851                    app.lastCpuTime = app.curCpuTime;
15852                }
15853            }
15854        }
15855    }
15856
15857    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15858            ProcessRecord TOP_APP, boolean doingAll, long now) {
15859        boolean success = true;
15860
15861        if (app.curRawAdj != app.setRawAdj) {
15862            if (wasKeeping && !app.keeping) {
15863                // This app is no longer something we want to keep.  Note
15864                // its current wake lock time to later know to kill it if
15865                // it is not behaving well.
15866                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15867                synchronized (stats) {
15868                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15869                            app.pid, SystemClock.elapsedRealtime());
15870                }
15871                app.lastCpuTime = app.curCpuTime;
15872            }
15873
15874            app.setRawAdj = app.curRawAdj;
15875        }
15876
15877        int changes = 0;
15878
15879        if (app.curAdj != app.setAdj) {
15880            ProcessList.setOomAdj(app.pid, app.curAdj);
15881            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15882                TAG, "Set " + app.pid + " " + app.processName +
15883                " adj " + app.curAdj + ": " + app.adjType);
15884            app.setAdj = app.curAdj;
15885        }
15886
15887        if (app.setSchedGroup != app.curSchedGroup) {
15888            app.setSchedGroup = app.curSchedGroup;
15889            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15890                    "Setting process group of " + app.processName
15891                    + " to " + app.curSchedGroup);
15892            if (app.waitingToKill != null &&
15893                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15894                killUnneededProcessLocked(app, app.waitingToKill);
15895                success = false;
15896            } else {
15897                if (true) {
15898                    long oldId = Binder.clearCallingIdentity();
15899                    try {
15900                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15901                    } catch (Exception e) {
15902                        Slog.w(TAG, "Failed setting process group of " + app.pid
15903                                + " to " + app.curSchedGroup);
15904                        e.printStackTrace();
15905                    } finally {
15906                        Binder.restoreCallingIdentity(oldId);
15907                    }
15908                } else {
15909                    if (app.thread != null) {
15910                        try {
15911                            app.thread.setSchedulingGroup(app.curSchedGroup);
15912                        } catch (RemoteException e) {
15913                        }
15914                    }
15915                }
15916                Process.setSwappiness(app.pid,
15917                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15918            }
15919        }
15920        if (app.repForegroundActivities != app.foregroundActivities) {
15921            app.repForegroundActivities = app.foregroundActivities;
15922            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15923        }
15924        if (app.repProcState != app.curProcState) {
15925            app.repProcState = app.curProcState;
15926            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
15927            if (app.thread != null) {
15928                try {
15929                    if (false) {
15930                        //RuntimeException h = new RuntimeException("here");
15931                        Slog.i(TAG, "Sending new process state " + app.repProcState
15932                                + " to " + app /*, h*/);
15933                    }
15934                    app.thread.setProcessState(app.repProcState);
15935                } catch (RemoteException e) {
15936                }
15937            }
15938        }
15939        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15940                app.setProcState)) {
15941            app.lastStateTime = now;
15942            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15943                    isSleeping(), now);
15944            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15945                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15946                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15947                    + (app.nextPssTime-now) + ": " + app);
15948        } else {
15949            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15950                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15951                requestPssLocked(app, app.setProcState);
15952                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15953                        isSleeping(), now);
15954            } else if (false && DEBUG_PSS) {
15955                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15956            }
15957        }
15958        if (app.setProcState != app.curProcState) {
15959            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15960                    "Proc state change of " + app.processName
15961                    + " to " + app.curProcState);
15962            app.setProcState = app.curProcState;
15963            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15964                app.notCachedSinceIdle = false;
15965            }
15966            if (!doingAll) {
15967                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15968            } else {
15969                app.procStateChanged = true;
15970            }
15971        }
15972
15973        if (changes != 0) {
15974            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15975            int i = mPendingProcessChanges.size()-1;
15976            ProcessChangeItem item = null;
15977            while (i >= 0) {
15978                item = mPendingProcessChanges.get(i);
15979                if (item.pid == app.pid) {
15980                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15981                    break;
15982                }
15983                i--;
15984            }
15985            if (i < 0) {
15986                // No existing item in pending changes; need a new one.
15987                final int NA = mAvailProcessChanges.size();
15988                if (NA > 0) {
15989                    item = mAvailProcessChanges.remove(NA-1);
15990                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15991                } else {
15992                    item = new ProcessChangeItem();
15993                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15994                }
15995                item.changes = 0;
15996                item.pid = app.pid;
15997                item.uid = app.info.uid;
15998                if (mPendingProcessChanges.size() == 0) {
15999                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
16000                            "*** Enqueueing dispatch processes changed!");
16001                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
16002                }
16003                mPendingProcessChanges.add(item);
16004            }
16005            item.changes |= changes;
16006            item.processState = app.repProcState;
16007            item.foregroundActivities = app.repForegroundActivities;
16008            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16009                    + Integer.toHexString(System.identityHashCode(item))
16010                    + " " + app.toShortString() + ": changes=" + item.changes
16011                    + " procState=" + item.processState
16012                    + " foreground=" + item.foregroundActivities
16013                    + " type=" + app.adjType + " source=" + app.adjSource
16014                    + " target=" + app.adjTarget);
16015        }
16016
16017        return success;
16018    }
16019
16020    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
16021        if (proc.thread != null && proc.baseProcessTracker != null) {
16022            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16023        }
16024    }
16025
16026    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16027            ProcessRecord TOP_APP, boolean doingAll, long now) {
16028        if (app.thread == null) {
16029            return false;
16030        }
16031
16032        final boolean wasKeeping = app.keeping;
16033
16034        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16035
16036        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now);
16037    }
16038
16039    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16040            boolean oomAdj) {
16041        if (isForeground != proc.foregroundServices) {
16042            proc.foregroundServices = isForeground;
16043            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16044                    proc.info.uid);
16045            if (isForeground) {
16046                if (curProcs == null) {
16047                    curProcs = new ArrayList<ProcessRecord>();
16048                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16049                }
16050                if (!curProcs.contains(proc)) {
16051                    curProcs.add(proc);
16052                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16053                            proc.info.packageName, proc.info.uid);
16054                }
16055            } else {
16056                if (curProcs != null) {
16057                    if (curProcs.remove(proc)) {
16058                        mBatteryStatsService.noteEvent(
16059                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16060                                proc.info.packageName, proc.info.uid);
16061                        if (curProcs.size() <= 0) {
16062                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16063                        }
16064                    }
16065                }
16066            }
16067            if (oomAdj) {
16068                updateOomAdjLocked();
16069            }
16070        }
16071    }
16072
16073    private final ActivityRecord resumedAppLocked() {
16074        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16075        String pkg;
16076        int uid;
16077        if (act != null && !act.sleeping) {
16078            pkg = act.packageName;
16079            uid = act.info.applicationInfo.uid;
16080        } else {
16081            pkg = null;
16082            uid = -1;
16083        }
16084        // Has the UID or resumed package name changed?
16085        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16086                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16087            if (mCurResumedPackage != null) {
16088                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16089                        mCurResumedPackage, mCurResumedUid);
16090            }
16091            mCurResumedPackage = pkg;
16092            mCurResumedUid = uid;
16093            if (mCurResumedPackage != null) {
16094                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16095                        mCurResumedPackage, mCurResumedUid);
16096            }
16097        }
16098        return act;
16099    }
16100
16101    final boolean updateOomAdjLocked(ProcessRecord app) {
16102        final ActivityRecord TOP_ACT = resumedAppLocked();
16103        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16104        final boolean wasCached = app.cached;
16105
16106        mAdjSeq++;
16107
16108        // This is the desired cached adjusment we want to tell it to use.
16109        // If our app is currently cached, we know it, and that is it.  Otherwise,
16110        // we don't know it yet, and it needs to now be cached we will then
16111        // need to do a complete oom adj.
16112        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16113                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16114        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16115                SystemClock.uptimeMillis());
16116        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16117            // Changed to/from cached state, so apps after it in the LRU
16118            // list may also be changed.
16119            updateOomAdjLocked();
16120        }
16121        return success;
16122    }
16123
16124    final void updateOomAdjLocked() {
16125        final ActivityRecord TOP_ACT = resumedAppLocked();
16126        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16127        final long now = SystemClock.uptimeMillis();
16128        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16129        final int N = mLruProcesses.size();
16130
16131        if (false) {
16132            RuntimeException e = new RuntimeException();
16133            e.fillInStackTrace();
16134            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16135        }
16136
16137        mAdjSeq++;
16138        mNewNumServiceProcs = 0;
16139        mNewNumAServiceProcs = 0;
16140
16141        final int emptyProcessLimit;
16142        final int cachedProcessLimit;
16143        if (mProcessLimit <= 0) {
16144            emptyProcessLimit = cachedProcessLimit = 0;
16145        } else if (mProcessLimit == 1) {
16146            emptyProcessLimit = 1;
16147            cachedProcessLimit = 0;
16148        } else {
16149            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16150            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16151        }
16152
16153        // Let's determine how many processes we have running vs.
16154        // how many slots we have for background processes; we may want
16155        // to put multiple processes in a slot of there are enough of
16156        // them.
16157        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16158                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16159        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16160        if (numEmptyProcs > cachedProcessLimit) {
16161            // If there are more empty processes than our limit on cached
16162            // processes, then use the cached process limit for the factor.
16163            // This ensures that the really old empty processes get pushed
16164            // down to the bottom, so if we are running low on memory we will
16165            // have a better chance at keeping around more cached processes
16166            // instead of a gazillion empty processes.
16167            numEmptyProcs = cachedProcessLimit;
16168        }
16169        int emptyFactor = numEmptyProcs/numSlots;
16170        if (emptyFactor < 1) emptyFactor = 1;
16171        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16172        if (cachedFactor < 1) cachedFactor = 1;
16173        int stepCached = 0;
16174        int stepEmpty = 0;
16175        int numCached = 0;
16176        int numEmpty = 0;
16177        int numTrimming = 0;
16178
16179        mNumNonCachedProcs = 0;
16180        mNumCachedHiddenProcs = 0;
16181
16182        // First update the OOM adjustment for each of the
16183        // application processes based on their current state.
16184        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16185        int nextCachedAdj = curCachedAdj+1;
16186        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16187        int nextEmptyAdj = curEmptyAdj+2;
16188        for (int i=N-1; i>=0; i--) {
16189            ProcessRecord app = mLruProcesses.get(i);
16190            if (!app.killedByAm && app.thread != null) {
16191                app.procStateChanged = false;
16192                final boolean wasKeeping = app.keeping;
16193                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16194
16195                // If we haven't yet assigned the final cached adj
16196                // to the process, do that now.
16197                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16198                    switch (app.curProcState) {
16199                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16200                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16201                            // This process is a cached process holding activities...
16202                            // assign it the next cached value for that type, and then
16203                            // step that cached level.
16204                            app.curRawAdj = curCachedAdj;
16205                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16206                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16207                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16208                                    + ")");
16209                            if (curCachedAdj != nextCachedAdj) {
16210                                stepCached++;
16211                                if (stepCached >= cachedFactor) {
16212                                    stepCached = 0;
16213                                    curCachedAdj = nextCachedAdj;
16214                                    nextCachedAdj += 2;
16215                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16216                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16217                                    }
16218                                }
16219                            }
16220                            break;
16221                        default:
16222                            // For everything else, assign next empty cached process
16223                            // level and bump that up.  Note that this means that
16224                            // long-running services that have dropped down to the
16225                            // cached level will be treated as empty (since their process
16226                            // state is still as a service), which is what we want.
16227                            app.curRawAdj = curEmptyAdj;
16228                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16229                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16230                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16231                                    + ")");
16232                            if (curEmptyAdj != nextEmptyAdj) {
16233                                stepEmpty++;
16234                                if (stepEmpty >= emptyFactor) {
16235                                    stepEmpty = 0;
16236                                    curEmptyAdj = nextEmptyAdj;
16237                                    nextEmptyAdj += 2;
16238                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16239                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16240                                    }
16241                                }
16242                            }
16243                            break;
16244                    }
16245                }
16246
16247                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now);
16248
16249                // Count the number of process types.
16250                switch (app.curProcState) {
16251                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16252                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16253                        mNumCachedHiddenProcs++;
16254                        numCached++;
16255                        if (numCached > cachedProcessLimit) {
16256                            killUnneededProcessLocked(app, "cached #" + numCached);
16257                        }
16258                        break;
16259                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16260                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16261                                && app.lastActivityTime < oldTime) {
16262                            killUnneededProcessLocked(app, "empty for "
16263                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16264                                    / 1000) + "s");
16265                        } else {
16266                            numEmpty++;
16267                            if (numEmpty > emptyProcessLimit) {
16268                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16269                            }
16270                        }
16271                        break;
16272                    default:
16273                        mNumNonCachedProcs++;
16274                        break;
16275                }
16276
16277                if (app.isolated && app.services.size() <= 0) {
16278                    // If this is an isolated process, and there are no
16279                    // services running in it, then the process is no longer
16280                    // needed.  We agressively kill these because we can by
16281                    // definition not re-use the same process again, and it is
16282                    // good to avoid having whatever code was running in them
16283                    // left sitting around after no longer needed.
16284                    killUnneededProcessLocked(app, "isolated not needed");
16285                }
16286
16287                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16288                        && !app.killedByAm) {
16289                    numTrimming++;
16290                }
16291            }
16292        }
16293
16294        mNumServiceProcs = mNewNumServiceProcs;
16295
16296        // Now determine the memory trimming level of background processes.
16297        // Unfortunately we need to start at the back of the list to do this
16298        // properly.  We only do this if the number of background apps we
16299        // are managing to keep around is less than half the maximum we desire;
16300        // if we are keeping a good number around, we'll let them use whatever
16301        // memory they want.
16302        final int numCachedAndEmpty = numCached + numEmpty;
16303        int memFactor;
16304        if (numCached <= ProcessList.TRIM_CACHED_APPS
16305                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16306            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16307                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16308            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16309                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16310            } else {
16311                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16312            }
16313        } else {
16314            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16315        }
16316        // We always allow the memory level to go up (better).  We only allow it to go
16317        // down if we are in a state where that is allowed, *and* the total number of processes
16318        // has gone down since last time.
16319        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16320                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16321                + " last=" + mLastNumProcesses);
16322        if (memFactor > mLastMemoryLevel) {
16323            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16324                memFactor = mLastMemoryLevel;
16325                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16326            }
16327        }
16328        mLastMemoryLevel = memFactor;
16329        mLastNumProcesses = mLruProcesses.size();
16330        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16331        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16332        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16333            if (mLowRamStartTime == 0) {
16334                mLowRamStartTime = now;
16335            }
16336            int step = 0;
16337            int fgTrimLevel;
16338            switch (memFactor) {
16339                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16340                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16341                    break;
16342                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16343                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16344                    break;
16345                default:
16346                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16347                    break;
16348            }
16349            int factor = numTrimming/3;
16350            int minFactor = 2;
16351            if (mHomeProcess != null) minFactor++;
16352            if (mPreviousProcess != null) minFactor++;
16353            if (factor < minFactor) factor = minFactor;
16354            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16355            for (int i=N-1; i>=0; i--) {
16356                ProcessRecord app = mLruProcesses.get(i);
16357                if (allChanged || app.procStateChanged) {
16358                    setProcessTrackerState(app, trackerMemFactor, now);
16359                    app.procStateChanged = false;
16360                }
16361                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16362                        && !app.killedByAm) {
16363                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16364                        try {
16365                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16366                                    "Trimming memory of " + app.processName
16367                                    + " to " + curLevel);
16368                            app.thread.scheduleTrimMemory(curLevel);
16369                        } catch (RemoteException e) {
16370                        }
16371                        if (false) {
16372                            // For now we won't do this; our memory trimming seems
16373                            // to be good enough at this point that destroying
16374                            // activities causes more harm than good.
16375                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16376                                    && app != mHomeProcess && app != mPreviousProcess) {
16377                                // Need to do this on its own message because the stack may not
16378                                // be in a consistent state at this point.
16379                                // For these apps we will also finish their activities
16380                                // to help them free memory.
16381                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16382                            }
16383                        }
16384                    }
16385                    app.trimMemoryLevel = curLevel;
16386                    step++;
16387                    if (step >= factor) {
16388                        step = 0;
16389                        switch (curLevel) {
16390                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16391                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16392                                break;
16393                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16394                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16395                                break;
16396                        }
16397                    }
16398                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16399                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16400                            && app.thread != null) {
16401                        try {
16402                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16403                                    "Trimming memory of heavy-weight " + app.processName
16404                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16405                            app.thread.scheduleTrimMemory(
16406                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16407                        } catch (RemoteException e) {
16408                        }
16409                    }
16410                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16411                } else {
16412                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16413                            || app.systemNoUi) && app.pendingUiClean) {
16414                        // If this application is now in the background and it
16415                        // had done UI, then give it the special trim level to
16416                        // have it free UI resources.
16417                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16418                        if (app.trimMemoryLevel < level && app.thread != null) {
16419                            try {
16420                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16421                                        "Trimming memory of bg-ui " + app.processName
16422                                        + " to " + level);
16423                                app.thread.scheduleTrimMemory(level);
16424                            } catch (RemoteException e) {
16425                            }
16426                        }
16427                        app.pendingUiClean = false;
16428                    }
16429                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16430                        try {
16431                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16432                                    "Trimming memory of fg " + app.processName
16433                                    + " to " + fgTrimLevel);
16434                            app.thread.scheduleTrimMemory(fgTrimLevel);
16435                        } catch (RemoteException e) {
16436                        }
16437                    }
16438                    app.trimMemoryLevel = fgTrimLevel;
16439                }
16440            }
16441        } else {
16442            if (mLowRamStartTime != 0) {
16443                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16444                mLowRamStartTime = 0;
16445            }
16446            for (int i=N-1; i>=0; i--) {
16447                ProcessRecord app = mLruProcesses.get(i);
16448                if (allChanged || app.procStateChanged) {
16449                    setProcessTrackerState(app, trackerMemFactor, now);
16450                    app.procStateChanged = false;
16451                }
16452                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16453                        || app.systemNoUi) && app.pendingUiClean) {
16454                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16455                            && app.thread != null) {
16456                        try {
16457                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16458                                    "Trimming memory of ui hidden " + app.processName
16459                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16460                            app.thread.scheduleTrimMemory(
16461                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16462                        } catch (RemoteException e) {
16463                        }
16464                    }
16465                    app.pendingUiClean = false;
16466                }
16467                app.trimMemoryLevel = 0;
16468            }
16469        }
16470
16471        if (mAlwaysFinishActivities) {
16472            // Need to do this on its own message because the stack may not
16473            // be in a consistent state at this point.
16474            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16475        }
16476
16477        if (allChanged) {
16478            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16479        }
16480
16481        if (mProcessStats.shouldWriteNowLocked(now)) {
16482            mHandler.post(new Runnable() {
16483                @Override public void run() {
16484                    synchronized (ActivityManagerService.this) {
16485                        mProcessStats.writeStateAsyncLocked();
16486                    }
16487                }
16488            });
16489        }
16490
16491        if (DEBUG_OOM_ADJ) {
16492            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16493        }
16494    }
16495
16496    final void trimApplications() {
16497        synchronized (this) {
16498            int i;
16499
16500            // First remove any unused application processes whose package
16501            // has been removed.
16502            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16503                final ProcessRecord app = mRemovedProcesses.get(i);
16504                if (app.activities.size() == 0
16505                        && app.curReceiver == null && app.services.size() == 0) {
16506                    Slog.i(
16507                        TAG, "Exiting empty application process "
16508                        + app.processName + " ("
16509                        + (app.thread != null ? app.thread.asBinder() : null)
16510                        + ")\n");
16511                    if (app.pid > 0 && app.pid != MY_PID) {
16512                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16513                                app.processName, app.setAdj, "empty");
16514                        app.killedByAm = true;
16515                        Process.killProcessQuiet(app.pid);
16516                    } else {
16517                        try {
16518                            app.thread.scheduleExit();
16519                        } catch (Exception e) {
16520                            // Ignore exceptions.
16521                        }
16522                    }
16523                    cleanUpApplicationRecordLocked(app, false, true, -1);
16524                    mRemovedProcesses.remove(i);
16525
16526                    if (app.persistent) {
16527                        if (app.persistent) {
16528                            addAppLocked(app.info, false, null /* ABI override */);
16529                        }
16530                    }
16531                }
16532            }
16533
16534            // Now update the oom adj for all processes.
16535            updateOomAdjLocked();
16536        }
16537    }
16538
16539    /** This method sends the specified signal to each of the persistent apps */
16540    public void signalPersistentProcesses(int sig) throws RemoteException {
16541        if (sig != Process.SIGNAL_USR1) {
16542            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16543        }
16544
16545        synchronized (this) {
16546            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16547                    != PackageManager.PERMISSION_GRANTED) {
16548                throw new SecurityException("Requires permission "
16549                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16550            }
16551
16552            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16553                ProcessRecord r = mLruProcesses.get(i);
16554                if (r.thread != null && r.persistent) {
16555                    Process.sendSignal(r.pid, sig);
16556                }
16557            }
16558        }
16559    }
16560
16561    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16562        if (proc == null || proc == mProfileProc) {
16563            proc = mProfileProc;
16564            path = mProfileFile;
16565            profileType = mProfileType;
16566            clearProfilerLocked();
16567        }
16568        if (proc == null) {
16569            return;
16570        }
16571        try {
16572            proc.thread.profilerControl(false, path, null, profileType);
16573        } catch (RemoteException e) {
16574            throw new IllegalStateException("Process disappeared");
16575        }
16576    }
16577
16578    private void clearProfilerLocked() {
16579        if (mProfileFd != null) {
16580            try {
16581                mProfileFd.close();
16582            } catch (IOException e) {
16583            }
16584        }
16585        mProfileApp = null;
16586        mProfileProc = null;
16587        mProfileFile = null;
16588        mProfileType = 0;
16589        mAutoStopProfiler = false;
16590    }
16591
16592    public boolean profileControl(String process, int userId, boolean start,
16593            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16594
16595        try {
16596            synchronized (this) {
16597                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16598                // its own permission.
16599                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16600                        != PackageManager.PERMISSION_GRANTED) {
16601                    throw new SecurityException("Requires permission "
16602                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16603                }
16604
16605                if (start && fd == null) {
16606                    throw new IllegalArgumentException("null fd");
16607                }
16608
16609                ProcessRecord proc = null;
16610                if (process != null) {
16611                    proc = findProcessLocked(process, userId, "profileControl");
16612                }
16613
16614                if (start && (proc == null || proc.thread == null)) {
16615                    throw new IllegalArgumentException("Unknown process: " + process);
16616                }
16617
16618                if (start) {
16619                    stopProfilerLocked(null, null, 0);
16620                    setProfileApp(proc.info, proc.processName, path, fd, false);
16621                    mProfileProc = proc;
16622                    mProfileType = profileType;
16623                    try {
16624                        fd = fd.dup();
16625                    } catch (IOException e) {
16626                        fd = null;
16627                    }
16628                    proc.thread.profilerControl(start, path, fd, profileType);
16629                    fd = null;
16630                    mProfileFd = null;
16631                } else {
16632                    stopProfilerLocked(proc, path, profileType);
16633                    if (fd != null) {
16634                        try {
16635                            fd.close();
16636                        } catch (IOException e) {
16637                        }
16638                    }
16639                }
16640
16641                return true;
16642            }
16643        } catch (RemoteException e) {
16644            throw new IllegalStateException("Process disappeared");
16645        } finally {
16646            if (fd != null) {
16647                try {
16648                    fd.close();
16649                } catch (IOException e) {
16650                }
16651            }
16652        }
16653    }
16654
16655    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16656        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16657                userId, true, true, callName, null);
16658        ProcessRecord proc = null;
16659        try {
16660            int pid = Integer.parseInt(process);
16661            synchronized (mPidsSelfLocked) {
16662                proc = mPidsSelfLocked.get(pid);
16663            }
16664        } catch (NumberFormatException e) {
16665        }
16666
16667        if (proc == null) {
16668            ArrayMap<String, SparseArray<ProcessRecord>> all
16669                    = mProcessNames.getMap();
16670            SparseArray<ProcessRecord> procs = all.get(process);
16671            if (procs != null && procs.size() > 0) {
16672                proc = procs.valueAt(0);
16673                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16674                    for (int i=1; i<procs.size(); i++) {
16675                        ProcessRecord thisProc = procs.valueAt(i);
16676                        if (thisProc.userId == userId) {
16677                            proc = thisProc;
16678                            break;
16679                        }
16680                    }
16681                }
16682            }
16683        }
16684
16685        return proc;
16686    }
16687
16688    public boolean dumpHeap(String process, int userId, boolean managed,
16689            String path, ParcelFileDescriptor fd) throws RemoteException {
16690
16691        try {
16692            synchronized (this) {
16693                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16694                // its own permission (same as profileControl).
16695                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16696                        != PackageManager.PERMISSION_GRANTED) {
16697                    throw new SecurityException("Requires permission "
16698                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16699                }
16700
16701                if (fd == null) {
16702                    throw new IllegalArgumentException("null fd");
16703                }
16704
16705                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16706                if (proc == null || proc.thread == null) {
16707                    throw new IllegalArgumentException("Unknown process: " + process);
16708                }
16709
16710                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16711                if (!isDebuggable) {
16712                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16713                        throw new SecurityException("Process not debuggable: " + proc);
16714                    }
16715                }
16716
16717                proc.thread.dumpHeap(managed, path, fd);
16718                fd = null;
16719                return true;
16720            }
16721        } catch (RemoteException e) {
16722            throw new IllegalStateException("Process disappeared");
16723        } finally {
16724            if (fd != null) {
16725                try {
16726                    fd.close();
16727                } catch (IOException e) {
16728                }
16729            }
16730        }
16731    }
16732
16733    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16734    public void monitor() {
16735        synchronized (this) { }
16736    }
16737
16738    void onCoreSettingsChange(Bundle settings) {
16739        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16740            ProcessRecord processRecord = mLruProcesses.get(i);
16741            try {
16742                if (processRecord.thread != null) {
16743                    processRecord.thread.setCoreSettings(settings);
16744                }
16745            } catch (RemoteException re) {
16746                /* ignore */
16747            }
16748        }
16749    }
16750
16751    // Multi-user methods
16752
16753    /**
16754     * Start user, if its not already running, but don't bring it to foreground.
16755     */
16756    @Override
16757    public boolean startUserInBackground(final int userId) {
16758        return startUser(userId, /* foreground */ false);
16759    }
16760
16761    /**
16762     * Refreshes the list of users related to the current user when either a
16763     * user switch happens or when a new related user is started in the
16764     * background.
16765     */
16766    private void updateCurrentProfileIdsLocked() {
16767        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16768                mCurrentUserId, false /* enabledOnly */);
16769        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16770        for (int i = 0; i < currentProfileIds.length; i++) {
16771            currentProfileIds[i] = profiles.get(i).id;
16772        }
16773        mCurrentProfileIds = currentProfileIds;
16774    }
16775
16776    private Set getProfileIdsLocked(int userId) {
16777        Set userIds = new HashSet<Integer>();
16778        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16779                userId, false /* enabledOnly */);
16780        for (UserInfo user : profiles) {
16781            userIds.add(Integer.valueOf(user.id));
16782        }
16783        return userIds;
16784    }
16785
16786    @Override
16787    public boolean switchUser(final int userId) {
16788        return startUser(userId, /* foregound */ true);
16789    }
16790
16791    private boolean startUser(final int userId, boolean foreground) {
16792        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
16793                != PackageManager.PERMISSION_GRANTED) {
16794            String msg = "Permission Denial: switchUser() from pid="
16795                    + Binder.getCallingPid()
16796                    + ", uid=" + Binder.getCallingUid()
16797                    + " requires " + INTERACT_ACROSS_USERS_FULL;
16798            Slog.w(TAG, msg);
16799            throw new SecurityException(msg);
16800        }
16801
16802        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16803
16804        final long ident = Binder.clearCallingIdentity();
16805        try {
16806            synchronized (this) {
16807                final int oldUserId = mCurrentUserId;
16808                if (oldUserId == userId) {
16809                    return true;
16810                }
16811
16812                mStackSupervisor.setLockTaskModeLocked(null, false);
16813
16814                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16815                if (userInfo == null) {
16816                    Slog.w(TAG, "No user info for user #" + userId);
16817                    return false;
16818                }
16819
16820                if (foreground) {
16821                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16822                            R.anim.screen_user_enter);
16823                }
16824
16825                boolean needStart = false;
16826
16827                // If the user we are switching to is not currently started, then
16828                // we need to start it now.
16829                if (mStartedUsers.get(userId) == null) {
16830                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16831                    updateStartedUserArrayLocked();
16832                    needStart = true;
16833                }
16834
16835                final Integer userIdInt = Integer.valueOf(userId);
16836                mUserLru.remove(userIdInt);
16837                mUserLru.add(userIdInt);
16838
16839                if (foreground) {
16840                    mCurrentUserId = userId;
16841                    updateCurrentProfileIdsLocked();
16842                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16843                    // Once the internal notion of the active user has switched, we lock the device
16844                    // with the option to show the user switcher on the keyguard.
16845                    mWindowManager.lockNow(null);
16846                } else {
16847                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16848                    updateCurrentProfileIdsLocked();
16849                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16850                    mUserLru.remove(currentUserIdInt);
16851                    mUserLru.add(currentUserIdInt);
16852                }
16853
16854                final UserStartedState uss = mStartedUsers.get(userId);
16855
16856                // Make sure user is in the started state.  If it is currently
16857                // stopping, we need to knock that off.
16858                if (uss.mState == UserStartedState.STATE_STOPPING) {
16859                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16860                    // so we can just fairly silently bring the user back from
16861                    // the almost-dead.
16862                    uss.mState = UserStartedState.STATE_RUNNING;
16863                    updateStartedUserArrayLocked();
16864                    needStart = true;
16865                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16866                    // This means ACTION_SHUTDOWN has been sent, so we will
16867                    // need to treat this as a new boot of the user.
16868                    uss.mState = UserStartedState.STATE_BOOTING;
16869                    updateStartedUserArrayLocked();
16870                    needStart = true;
16871                }
16872
16873                if (uss.mState == UserStartedState.STATE_BOOTING) {
16874                    // Booting up a new user, need to tell system services about it.
16875                    // Note that this is on the same handler as scheduling of broadcasts,
16876                    // which is important because it needs to go first.
16877                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
16878                }
16879
16880                if (foreground) {
16881                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId));
16882                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16883                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16884                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16885                            oldUserId, userId, uss));
16886                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16887                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16888                }
16889
16890                if (needStart) {
16891                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16892                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16893                            | Intent.FLAG_RECEIVER_FOREGROUND);
16894                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16895                    broadcastIntentLocked(null, null, intent,
16896                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16897                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16898                }
16899
16900                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16901                    if (userId != UserHandle.USER_OWNER) {
16902                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16903                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16904                        broadcastIntentLocked(null, null, intent, null,
16905                                new IIntentReceiver.Stub() {
16906                                    public void performReceive(Intent intent, int resultCode,
16907                                            String data, Bundle extras, boolean ordered,
16908                                            boolean sticky, int sendingUser) {
16909                                        userInitialized(uss, userId);
16910                                    }
16911                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16912                                true, false, MY_PID, Process.SYSTEM_UID,
16913                                userId);
16914                        uss.initializing = true;
16915                    } else {
16916                        getUserManagerLocked().makeInitialized(userInfo.id);
16917                    }
16918                }
16919
16920                if (foreground) {
16921                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16922                    if (homeInFront) {
16923                        startHomeActivityLocked(userId);
16924                    } else {
16925                        mStackSupervisor.resumeTopActivitiesLocked();
16926                    }
16927                    EventLogTags.writeAmSwitchUser(userId);
16928                    getUserManagerLocked().userForeground(userId);
16929                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16930                } else {
16931                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
16932                }
16933
16934                if (needStart) {
16935                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16936                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16937                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16938                    broadcastIntentLocked(null, null, intent,
16939                            null, new IIntentReceiver.Stub() {
16940                                @Override
16941                                public void performReceive(Intent intent, int resultCode, String data,
16942                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16943                                        throws RemoteException {
16944                                }
16945                            }, 0, null, null,
16946                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16947                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16948                }
16949            }
16950        } finally {
16951            Binder.restoreCallingIdentity(ident);
16952        }
16953
16954        return true;
16955    }
16956
16957    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16958        long ident = Binder.clearCallingIdentity();
16959        try {
16960            Intent intent;
16961            if (oldUserId >= 0) {
16962                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16963                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16964                        | Intent.FLAG_RECEIVER_FOREGROUND);
16965                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16966                broadcastIntentLocked(null, null, intent,
16967                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16968                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16969            }
16970            if (newUserId >= 0) {
16971                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16972                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16973                        | Intent.FLAG_RECEIVER_FOREGROUND);
16974                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16975                broadcastIntentLocked(null, null, intent,
16976                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16977                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16978                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16979                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16980                        | Intent.FLAG_RECEIVER_FOREGROUND);
16981                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16982                broadcastIntentLocked(null, null, intent,
16983                        null, null, 0, null, null,
16984                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16985                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16986            }
16987        } finally {
16988            Binder.restoreCallingIdentity(ident);
16989        }
16990    }
16991
16992    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16993            final int newUserId) {
16994        final int N = mUserSwitchObservers.beginBroadcast();
16995        if (N > 0) {
16996            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16997                int mCount = 0;
16998                @Override
16999                public void sendResult(Bundle data) throws RemoteException {
17000                    synchronized (ActivityManagerService.this) {
17001                        if (mCurUserSwitchCallback == this) {
17002                            mCount++;
17003                            if (mCount == N) {
17004                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17005                            }
17006                        }
17007                    }
17008                }
17009            };
17010            synchronized (this) {
17011                uss.switching = true;
17012                mCurUserSwitchCallback = callback;
17013            }
17014            for (int i=0; i<N; i++) {
17015                try {
17016                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17017                            newUserId, callback);
17018                } catch (RemoteException e) {
17019                }
17020            }
17021        } else {
17022            synchronized (this) {
17023                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17024            }
17025        }
17026        mUserSwitchObservers.finishBroadcast();
17027    }
17028
17029    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17030        synchronized (this) {
17031            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17032            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17033        }
17034    }
17035
17036    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17037        mCurUserSwitchCallback = null;
17038        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17039        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17040                oldUserId, newUserId, uss));
17041    }
17042
17043    void userInitialized(UserStartedState uss, int newUserId) {
17044        completeSwitchAndInitalize(uss, newUserId, true, false);
17045    }
17046
17047    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17048        completeSwitchAndInitalize(uss, newUserId, false, true);
17049    }
17050
17051    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17052            boolean clearInitializing, boolean clearSwitching) {
17053        boolean unfrozen = false;
17054        synchronized (this) {
17055            if (clearInitializing) {
17056                uss.initializing = false;
17057                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17058            }
17059            if (clearSwitching) {
17060                uss.switching = false;
17061            }
17062            if (!uss.switching && !uss.initializing) {
17063                mWindowManager.stopFreezingScreen();
17064                unfrozen = true;
17065            }
17066        }
17067        if (unfrozen) {
17068            final int N = mUserSwitchObservers.beginBroadcast();
17069            for (int i=0; i<N; i++) {
17070                try {
17071                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17072                } catch (RemoteException e) {
17073                }
17074            }
17075            mUserSwitchObservers.finishBroadcast();
17076        }
17077    }
17078
17079    void scheduleStartProfilesLocked() {
17080        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17081            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17082                    DateUtils.SECOND_IN_MILLIS);
17083        }
17084    }
17085
17086    void startProfilesLocked() {
17087        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17088        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17089                mCurrentUserId, false /* enabledOnly */);
17090        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17091        for (UserInfo user : profiles) {
17092            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17093                    && user.id != mCurrentUserId) {
17094                toStart.add(user);
17095            }
17096        }
17097        final int n = toStart.size();
17098        int i = 0;
17099        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17100            startUserInBackground(toStart.get(i).id);
17101        }
17102        if (i < n) {
17103            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17104        }
17105    }
17106
17107    void finishUserBoot(UserStartedState uss) {
17108        synchronized (this) {
17109            if (uss.mState == UserStartedState.STATE_BOOTING
17110                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17111                uss.mState = UserStartedState.STATE_RUNNING;
17112                final int userId = uss.mHandle.getIdentifier();
17113                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17114                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17115                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17116                broadcastIntentLocked(null, null, intent,
17117                        null, null, 0, null, null,
17118                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17119                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17120            }
17121        }
17122    }
17123
17124    void finishUserSwitch(UserStartedState uss) {
17125        synchronized (this) {
17126            finishUserBoot(uss);
17127
17128            startProfilesLocked();
17129
17130            int num = mUserLru.size();
17131            int i = 0;
17132            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17133                Integer oldUserId = mUserLru.get(i);
17134                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17135                if (oldUss == null) {
17136                    // Shouldn't happen, but be sane if it does.
17137                    mUserLru.remove(i);
17138                    num--;
17139                    continue;
17140                }
17141                if (oldUss.mState == UserStartedState.STATE_STOPPING
17142                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17143                    // This user is already stopping, doesn't count.
17144                    num--;
17145                    i++;
17146                    continue;
17147                }
17148                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17149                    // Owner and current can't be stopped, but count as running.
17150                    i++;
17151                    continue;
17152                }
17153                // This is a user to be stopped.
17154                stopUserLocked(oldUserId, null);
17155                num--;
17156                i++;
17157            }
17158        }
17159    }
17160
17161    @Override
17162    public int stopUser(final int userId, final IStopUserCallback callback) {
17163        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17164                != PackageManager.PERMISSION_GRANTED) {
17165            String msg = "Permission Denial: switchUser() from pid="
17166                    + Binder.getCallingPid()
17167                    + ", uid=" + Binder.getCallingUid()
17168                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17169            Slog.w(TAG, msg);
17170            throw new SecurityException(msg);
17171        }
17172        if (userId <= 0) {
17173            throw new IllegalArgumentException("Can't stop primary user " + userId);
17174        }
17175        synchronized (this) {
17176            return stopUserLocked(userId, callback);
17177        }
17178    }
17179
17180    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17181        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17182        if (mCurrentUserId == userId) {
17183            return ActivityManager.USER_OP_IS_CURRENT;
17184        }
17185
17186        final UserStartedState uss = mStartedUsers.get(userId);
17187        if (uss == null) {
17188            // User is not started, nothing to do...  but we do need to
17189            // callback if requested.
17190            if (callback != null) {
17191                mHandler.post(new Runnable() {
17192                    @Override
17193                    public void run() {
17194                        try {
17195                            callback.userStopped(userId);
17196                        } catch (RemoteException e) {
17197                        }
17198                    }
17199                });
17200            }
17201            return ActivityManager.USER_OP_SUCCESS;
17202        }
17203
17204        if (callback != null) {
17205            uss.mStopCallbacks.add(callback);
17206        }
17207
17208        if (uss.mState != UserStartedState.STATE_STOPPING
17209                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17210            uss.mState = UserStartedState.STATE_STOPPING;
17211            updateStartedUserArrayLocked();
17212
17213            long ident = Binder.clearCallingIdentity();
17214            try {
17215                // We are going to broadcast ACTION_USER_STOPPING and then
17216                // once that is done send a final ACTION_SHUTDOWN and then
17217                // stop the user.
17218                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17219                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17220                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17221                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17222                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17223                // This is the result receiver for the final shutdown broadcast.
17224                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17225                    @Override
17226                    public void performReceive(Intent intent, int resultCode, String data,
17227                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17228                        finishUserStop(uss);
17229                    }
17230                };
17231                // This is the result receiver for the initial stopping broadcast.
17232                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17233                    @Override
17234                    public void performReceive(Intent intent, int resultCode, String data,
17235                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17236                        // On to the next.
17237                        synchronized (ActivityManagerService.this) {
17238                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17239                                // Whoops, we are being started back up.  Abort, abort!
17240                                return;
17241                            }
17242                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17243                        }
17244                        mSystemServiceManager.stopUser(userId);
17245                        broadcastIntentLocked(null, null, shutdownIntent,
17246                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17247                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17248                    }
17249                };
17250                // Kick things off.
17251                broadcastIntentLocked(null, null, stoppingIntent,
17252                        null, stoppingReceiver, 0, null, null,
17253                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17254                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17255            } finally {
17256                Binder.restoreCallingIdentity(ident);
17257            }
17258        }
17259
17260        return ActivityManager.USER_OP_SUCCESS;
17261    }
17262
17263    void finishUserStop(UserStartedState uss) {
17264        final int userId = uss.mHandle.getIdentifier();
17265        boolean stopped;
17266        ArrayList<IStopUserCallback> callbacks;
17267        synchronized (this) {
17268            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17269            if (mStartedUsers.get(userId) != uss) {
17270                stopped = false;
17271            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17272                stopped = false;
17273            } else {
17274                stopped = true;
17275                // User can no longer run.
17276                mStartedUsers.remove(userId);
17277                mUserLru.remove(Integer.valueOf(userId));
17278                updateStartedUserArrayLocked();
17279
17280                // Clean up all state and processes associated with the user.
17281                // Kill all the processes for the user.
17282                forceStopUserLocked(userId, "finish user");
17283            }
17284        }
17285
17286        for (int i=0; i<callbacks.size(); i++) {
17287            try {
17288                if (stopped) callbacks.get(i).userStopped(userId);
17289                else callbacks.get(i).userStopAborted(userId);
17290            } catch (RemoteException e) {
17291            }
17292        }
17293
17294        if (stopped) {
17295            mSystemServiceManager.cleanupUser(userId);
17296            synchronized (this) {
17297                mStackSupervisor.removeUserLocked(userId);
17298            }
17299        }
17300    }
17301
17302    @Override
17303    public UserInfo getCurrentUser() {
17304        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17305                != PackageManager.PERMISSION_GRANTED) && (
17306                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17307                != PackageManager.PERMISSION_GRANTED)) {
17308            String msg = "Permission Denial: getCurrentUser() from pid="
17309                    + Binder.getCallingPid()
17310                    + ", uid=" + Binder.getCallingUid()
17311                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17312            Slog.w(TAG, msg);
17313            throw new SecurityException(msg);
17314        }
17315        synchronized (this) {
17316            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17317        }
17318    }
17319
17320    int getCurrentUserIdLocked() {
17321        return mCurrentUserId;
17322    }
17323
17324    @Override
17325    public boolean isUserRunning(int userId, boolean orStopped) {
17326        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17327                != PackageManager.PERMISSION_GRANTED) {
17328            String msg = "Permission Denial: isUserRunning() from pid="
17329                    + Binder.getCallingPid()
17330                    + ", uid=" + Binder.getCallingUid()
17331                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17332            Slog.w(TAG, msg);
17333            throw new SecurityException(msg);
17334        }
17335        synchronized (this) {
17336            return isUserRunningLocked(userId, orStopped);
17337        }
17338    }
17339
17340    boolean isUserRunningLocked(int userId, boolean orStopped) {
17341        UserStartedState state = mStartedUsers.get(userId);
17342        if (state == null) {
17343            return false;
17344        }
17345        if (orStopped) {
17346            return true;
17347        }
17348        return state.mState != UserStartedState.STATE_STOPPING
17349                && state.mState != UserStartedState.STATE_SHUTDOWN;
17350    }
17351
17352    @Override
17353    public int[] getRunningUserIds() {
17354        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17355                != PackageManager.PERMISSION_GRANTED) {
17356            String msg = "Permission Denial: isUserRunning() from pid="
17357                    + Binder.getCallingPid()
17358                    + ", uid=" + Binder.getCallingUid()
17359                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17360            Slog.w(TAG, msg);
17361            throw new SecurityException(msg);
17362        }
17363        synchronized (this) {
17364            return mStartedUserArray;
17365        }
17366    }
17367
17368    private void updateStartedUserArrayLocked() {
17369        int num = 0;
17370        for (int i=0; i<mStartedUsers.size();  i++) {
17371            UserStartedState uss = mStartedUsers.valueAt(i);
17372            // This list does not include stopping users.
17373            if (uss.mState != UserStartedState.STATE_STOPPING
17374                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17375                num++;
17376            }
17377        }
17378        mStartedUserArray = new int[num];
17379        num = 0;
17380        for (int i=0; i<mStartedUsers.size();  i++) {
17381            UserStartedState uss = mStartedUsers.valueAt(i);
17382            if (uss.mState != UserStartedState.STATE_STOPPING
17383                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17384                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17385                num++;
17386            }
17387        }
17388    }
17389
17390    @Override
17391    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17392        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17393                != PackageManager.PERMISSION_GRANTED) {
17394            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17395                    + Binder.getCallingPid()
17396                    + ", uid=" + Binder.getCallingUid()
17397                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17398            Slog.w(TAG, msg);
17399            throw new SecurityException(msg);
17400        }
17401
17402        mUserSwitchObservers.register(observer);
17403    }
17404
17405    @Override
17406    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17407        mUserSwitchObservers.unregister(observer);
17408    }
17409
17410    private boolean userExists(int userId) {
17411        if (userId == 0) {
17412            return true;
17413        }
17414        UserManagerService ums = getUserManagerLocked();
17415        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17416    }
17417
17418    int[] getUsersLocked() {
17419        UserManagerService ums = getUserManagerLocked();
17420        return ums != null ? ums.getUserIds() : new int[] { 0 };
17421    }
17422
17423    UserManagerService getUserManagerLocked() {
17424        if (mUserManager == null) {
17425            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17426            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17427        }
17428        return mUserManager;
17429    }
17430
17431    private int applyUserId(int uid, int userId) {
17432        return UserHandle.getUid(userId, uid);
17433    }
17434
17435    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17436        if (info == null) return null;
17437        ApplicationInfo newInfo = new ApplicationInfo(info);
17438        newInfo.uid = applyUserId(info.uid, userId);
17439        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17440                + info.packageName;
17441        return newInfo;
17442    }
17443
17444    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17445        if (aInfo == null
17446                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17447            return aInfo;
17448        }
17449
17450        ActivityInfo info = new ActivityInfo(aInfo);
17451        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17452        return info;
17453    }
17454
17455    private final class LocalService extends ActivityManagerInternal {
17456        @Override
17457        public void goingToSleep() {
17458            ActivityManagerService.this.goingToSleep();
17459        }
17460
17461        @Override
17462        public void wakingUp() {
17463            ActivityManagerService.this.wakingUp();
17464        }
17465    }
17466
17467    /**
17468     * An implementation of IAppTask, that allows an app to manage its own tasks via
17469     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17470     * only the process that calls getAppTasks() can call the AppTask methods.
17471     */
17472    class AppTaskImpl extends IAppTask.Stub {
17473        private int mTaskId;
17474        private int mCallingUid;
17475
17476        public AppTaskImpl(int taskId, int callingUid) {
17477            mTaskId = taskId;
17478            mCallingUid = callingUid;
17479        }
17480
17481        @Override
17482        public void finishAndRemoveTask() {
17483            // Ensure that we are called from the same process that created this AppTask
17484            if (mCallingUid != Binder.getCallingUid()) {
17485                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17486                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17487                return;
17488            }
17489
17490            synchronized (ActivityManagerService.this) {
17491                long origId = Binder.clearCallingIdentity();
17492                try {
17493                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17494                    if (tr != null) {
17495                        // Only kill the process if we are not a new document
17496                        int flags = tr.getBaseIntent().getFlags();
17497                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17498                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17499                        removeTaskByIdLocked(mTaskId,
17500                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17501                    }
17502                } finally {
17503                    Binder.restoreCallingIdentity(origId);
17504                }
17505            }
17506        }
17507
17508        @Override
17509        public ActivityManager.RecentTaskInfo getTaskInfo() {
17510            // Ensure that we are called from the same process that created this AppTask
17511            if (mCallingUid != Binder.getCallingUid()) {
17512                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17513                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17514                return null;
17515            }
17516
17517            synchronized (ActivityManagerService.this) {
17518                long origId = Binder.clearCallingIdentity();
17519                try {
17520                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17521                    if (tr != null) {
17522                        return createRecentTaskInfoFromTaskRecord(tr);
17523                    }
17524                } finally {
17525                    Binder.restoreCallingIdentity(origId);
17526                }
17527                return null;
17528            }
17529        }
17530    }
17531}
17532