ActivityManagerService.java revision 852975d5377bfe5f4abc9d2a28e301aa2fa99994
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;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24import static com.android.internal.util.XmlUtils.readIntAttribute;
25import static com.android.internal.util.XmlUtils.readLongAttribute;
26import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27import static com.android.internal.util.XmlUtils.writeIntAttribute;
28import static com.android.internal.util.XmlUtils.writeLongAttribute;
29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31import static org.xmlpull.v1.XmlPullParser.START_TAG;
32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
33
34import android.Manifest;
35import android.app.AppOpsManager;
36import android.app.ApplicationThreadNative;
37import android.app.IActivityContainer;
38import android.app.IActivityContainerCallback;
39import android.app.IAppTask;
40import android.app.admin.DevicePolicyManager;
41import android.app.usage.UsageEvents;
42import android.app.usage.UsageStatsManagerInternal;
43import android.appwidget.AppWidgetManager;
44import android.content.res.Resources;
45import android.graphics.Bitmap;
46import android.graphics.Point;
47import android.graphics.Rect;
48import android.os.BatteryStats;
49import android.os.PersistableBundle;
50import android.service.voice.IVoiceInteractionSession;
51import android.util.ArrayMap;
52import android.util.ArraySet;
53import android.util.SparseIntArray;
54
55import com.android.internal.R;
56import com.android.internal.annotations.GuardedBy;
57import com.android.internal.app.IAppOpsService;
58import com.android.internal.app.IVoiceInteractor;
59import com.android.internal.app.ProcessMap;
60import com.android.internal.app.ProcessStats;
61import com.android.internal.content.PackageMonitor;
62import com.android.internal.os.BackgroundThread;
63import com.android.internal.os.BatteryStatsImpl;
64import com.android.internal.os.ProcessCpuTracker;
65import com.android.internal.os.TransferPipe;
66import com.android.internal.os.Zygote;
67import com.android.internal.util.FastPrintWriter;
68import com.android.internal.util.FastXmlSerializer;
69import com.android.internal.util.MemInfoReader;
70import com.android.internal.util.Preconditions;
71import com.android.server.AppOpsService;
72import com.android.server.AttributeCache;
73import com.android.server.IntentResolver;
74import com.android.server.LocalServices;
75import com.android.server.ServiceThread;
76import com.android.server.SystemService;
77import com.android.server.SystemServiceManager;
78import com.android.server.Watchdog;
79import com.android.server.am.ActivityStack.ActivityState;
80import com.android.server.firewall.IntentFirewall;
81import com.android.server.pm.UserManagerService;
82import com.android.server.wm.AppTransition;
83import com.android.server.wm.WindowManagerService;
84import com.google.android.collect.Lists;
85import com.google.android.collect.Maps;
86
87import libcore.io.IoUtils;
88
89import org.xmlpull.v1.XmlPullParser;
90import org.xmlpull.v1.XmlPullParserException;
91import org.xmlpull.v1.XmlSerializer;
92
93import android.app.Activity;
94import android.app.ActivityManager;
95import android.app.ActivityManager.RunningTaskInfo;
96import android.app.ActivityManager.StackInfo;
97import android.app.ActivityManagerInternal;
98import android.app.ActivityManagerNative;
99import android.app.ActivityOptions;
100import android.app.ActivityThread;
101import android.app.AlertDialog;
102import android.app.AppGlobals;
103import android.app.ApplicationErrorReport;
104import android.app.Dialog;
105import android.app.IActivityController;
106import android.app.IApplicationThread;
107import android.app.IInstrumentationWatcher;
108import android.app.INotificationManager;
109import android.app.IProcessObserver;
110import android.app.IServiceConnection;
111import android.app.IStopUserCallback;
112import android.app.IUiAutomationConnection;
113import android.app.IUserSwitchObserver;
114import android.app.Instrumentation;
115import android.app.Notification;
116import android.app.NotificationManager;
117import android.app.PendingIntent;
118import android.app.backup.IBackupManager;
119import android.content.ActivityNotFoundException;
120import android.content.BroadcastReceiver;
121import android.content.ClipData;
122import android.content.ComponentCallbacks2;
123import android.content.ComponentName;
124import android.content.ContentProvider;
125import android.content.ContentResolver;
126import android.content.Context;
127import android.content.DialogInterface;
128import android.content.IContentProvider;
129import android.content.IIntentReceiver;
130import android.content.IIntentSender;
131import android.content.Intent;
132import android.content.IntentFilter;
133import android.content.IntentSender;
134import android.content.pm.ActivityInfo;
135import android.content.pm.ApplicationInfo;
136import android.content.pm.ConfigurationInfo;
137import android.content.pm.IPackageDataObserver;
138import android.content.pm.IPackageManager;
139import android.content.pm.InstrumentationInfo;
140import android.content.pm.PackageInfo;
141import android.content.pm.PackageManager;
142import android.content.pm.ParceledListSlice;
143import android.content.pm.UserInfo;
144import android.content.pm.PackageManager.NameNotFoundException;
145import android.content.pm.PathPermission;
146import android.content.pm.ProviderInfo;
147import android.content.pm.ResolveInfo;
148import android.content.pm.ServiceInfo;
149import android.content.res.CompatibilityInfo;
150import android.content.res.Configuration;
151import android.net.Proxy;
152import android.net.ProxyInfo;
153import android.net.Uri;
154import android.os.Binder;
155import android.os.Build;
156import android.os.Bundle;
157import android.os.Debug;
158import android.os.DropBoxManager;
159import android.os.Environment;
160import android.os.FactoryTest;
161import android.os.FileObserver;
162import android.os.FileUtils;
163import android.os.Handler;
164import android.os.IBinder;
165import android.os.IPermissionController;
166import android.os.IRemoteCallback;
167import android.os.IUserManager;
168import android.os.Looper;
169import android.os.Message;
170import android.os.Parcel;
171import android.os.ParcelFileDescriptor;
172import android.os.Process;
173import android.os.RemoteCallbackList;
174import android.os.RemoteException;
175import android.os.SELinux;
176import android.os.ServiceManager;
177import android.os.StrictMode;
178import android.os.SystemClock;
179import android.os.SystemProperties;
180import android.os.UpdateLock;
181import android.os.UserHandle;
182import android.provider.Settings;
183import android.text.format.DateUtils;
184import android.text.format.Time;
185import android.util.AtomicFile;
186import android.util.EventLog;
187import android.util.Log;
188import android.util.Pair;
189import android.util.PrintWriterPrinter;
190import android.util.Slog;
191import android.util.SparseArray;
192import android.util.TimeUtils;
193import android.util.Xml;
194import android.view.Gravity;
195import android.view.LayoutInflater;
196import android.view.View;
197import android.view.WindowManager;
198
199import java.io.BufferedInputStream;
200import java.io.BufferedOutputStream;
201import java.io.DataInputStream;
202import java.io.DataOutputStream;
203import java.io.File;
204import java.io.FileDescriptor;
205import java.io.FileInputStream;
206import java.io.FileNotFoundException;
207import java.io.FileOutputStream;
208import java.io.IOException;
209import java.io.InputStreamReader;
210import java.io.PrintWriter;
211import java.io.StringWriter;
212import java.lang.ref.WeakReference;
213import java.util.ArrayList;
214import java.util.Arrays;
215import java.util.Collections;
216import java.util.Comparator;
217import java.util.HashMap;
218import java.util.HashSet;
219import java.util.Iterator;
220import java.util.List;
221import java.util.Locale;
222import java.util.Map;
223import java.util.Set;
224import java.util.concurrent.atomic.AtomicBoolean;
225import java.util.concurrent.atomic.AtomicLong;
226
227public final class ActivityManagerService extends ActivityManagerNative
228        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
229
230    private static final String USER_DATA_DIR = "/data/user/";
231    // File that stores last updated system version and called preboot receivers
232    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
233
234    static final String TAG = "ActivityManager";
235    static final String TAG_MU = "ActivityManagerServiceMU";
236    static final boolean DEBUG = false;
237    static final boolean localLOGV = DEBUG;
238    static final boolean DEBUG_BACKUP = localLOGV || false;
239    static final boolean DEBUG_BROADCAST = localLOGV || false;
240    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
241    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
242    static final boolean DEBUG_CLEANUP = localLOGV || false;
243    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
244    static final boolean DEBUG_FOCUS = false;
245    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
246    static final boolean DEBUG_MU = localLOGV || false;
247    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
248    static final boolean DEBUG_LRU = localLOGV || false;
249    static final boolean DEBUG_PAUSE = localLOGV || false;
250    static final boolean DEBUG_POWER = localLOGV || false;
251    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
252    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
253    static final boolean DEBUG_PROCESSES = localLOGV || false;
254    static final boolean DEBUG_PROVIDER = localLOGV || false;
255    static final boolean DEBUG_RESULTS = localLOGV || false;
256    static final boolean DEBUG_SERVICE = localLOGV || false;
257    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
258    static final boolean DEBUG_STACK = localLOGV || false;
259    static final boolean DEBUG_SWITCH = localLOGV || false;
260    static final boolean DEBUG_TASKS = localLOGV || false;
261    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
262    static final boolean DEBUG_TRANSITION = localLOGV || false;
263    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
264    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
265    static final boolean DEBUG_VISBILITY = localLOGV || false;
266    static final boolean DEBUG_PSS = localLOGV || false;
267    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
268    static final boolean DEBUG_RECENTS = localLOGV || false;
269    static final boolean VALIDATE_TOKENS = false;
270    static final boolean SHOW_ACTIVITY_START_TIME = true;
271
272    // Control over CPU and battery monitoring.
273    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
274    static final boolean MONITOR_CPU_USAGE = true;
275    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
276    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
277    static final boolean MONITOR_THREAD_CPU_USAGE = false;
278
279    // The flags that are set for all calls we make to the package manager.
280    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
281
282    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
283
284    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
285
286    // Maximum number recent bitmaps to keep in memory.
287    static final int MAX_RECENT_BITMAPS = 5;
288
289    // Amount of time after a call to stopAppSwitches() during which we will
290    // prevent further untrusted switches from happening.
291    static final long APP_SWITCH_DELAY_TIME = 5*1000;
292
293    // How long we wait for a launched process to attach to the activity manager
294    // before we decide it's never going to come up for real.
295    static final int PROC_START_TIMEOUT = 10*1000;
296
297    // How long we wait for a launched process to attach to the activity manager
298    // before we decide it's never going to come up for real, when the process was
299    // started with a wrapper for instrumentation (such as Valgrind) because it
300    // could take much longer than usual.
301    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
302
303    // How long to wait after going idle before forcing apps to GC.
304    static final int GC_TIMEOUT = 5*1000;
305
306    // The minimum amount of time between successive GC requests for a process.
307    static final int GC_MIN_INTERVAL = 60*1000;
308
309    // The minimum amount of time between successive PSS requests for a process.
310    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
311
312    // The minimum amount of time between successive PSS requests for a process
313    // when the request is due to the memory state being lowered.
314    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
315
316    // The rate at which we check for apps using excessive power -- 15 mins.
317    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
318
319    // The minimum sample duration we will allow before deciding we have
320    // enough data on wake locks to start killing things.
321    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
322
323    // The minimum sample duration we will allow before deciding we have
324    // enough data on CPU usage to start killing things.
325    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
326
327    // How long we allow a receiver to run before giving up on it.
328    static final int BROADCAST_FG_TIMEOUT = 10*1000;
329    static final int BROADCAST_BG_TIMEOUT = 60*1000;
330
331    // How long we wait until we timeout on key dispatching.
332    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
333
334    // How long we wait until we timeout on key dispatching during instrumentation.
335    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
336
337    // Amount of time we wait for observers to handle a user switch before
338    // giving up on them and unfreezing the screen.
339    static final int USER_SWITCH_TIMEOUT = 2*1000;
340
341    // Maximum number of users we allow to be running at a time.
342    static final int MAX_RUNNING_USERS = 3;
343
344    // How long to wait in getAssistContextExtras for the activity and foreground services
345    // to respond with the result.
346    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
347
348    // Maximum number of persisted Uri grants a package is allowed
349    static final int MAX_PERSISTED_URI_GRANTS = 128;
350
351    static final int MY_PID = Process.myPid();
352
353    static final String[] EMPTY_STRING_ARRAY = new String[0];
354
355    // How many bytes to write into the dropbox log before truncating
356    static final int DROPBOX_MAX_SIZE = 256 * 1024;
357
358    // Access modes for handleIncomingUser.
359    static final int ALLOW_NON_FULL = 0;
360    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
361    static final int ALLOW_FULL_ONLY = 2;
362
363    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
364
365    /** All system services */
366    SystemServiceManager mSystemServiceManager;
367
368    /** Run all ActivityStacks through this */
369    ActivityStackSupervisor mStackSupervisor;
370
371    public IntentFirewall mIntentFirewall;
372
373    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
374    // default actuion automatically.  Important for devices without direct input
375    // devices.
376    private boolean mShowDialogs = true;
377
378    BroadcastQueue mFgBroadcastQueue;
379    BroadcastQueue mBgBroadcastQueue;
380    // Convenient for easy iteration over the queues. Foreground is first
381    // so that dispatch of foreground broadcasts gets precedence.
382    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
383
384    BroadcastQueue broadcastQueueForIntent(Intent intent) {
385        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
386        if (DEBUG_BACKGROUND_BROADCAST) {
387            Slog.i(TAG, "Broadcast intent " + intent + " on "
388                    + (isFg ? "foreground" : "background")
389                    + " queue");
390        }
391        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
392    }
393
394    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
395        for (BroadcastQueue queue : mBroadcastQueues) {
396            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
397            if (r != null) {
398                return r;
399            }
400        }
401        return null;
402    }
403
404    /**
405     * Activity we have told the window manager to have key focus.
406     */
407    ActivityRecord mFocusedActivity = null;
408
409    /**
410     * List of intents that were used to start the most recent tasks.
411     */
412    ArrayList<TaskRecord> mRecentTasks;
413    ArraySet<TaskRecord> mTmpRecents = new ArraySet<TaskRecord>();
414
415    /**
416     * For addAppTask: cached of the last activity component that was added.
417     */
418    ComponentName mLastAddedTaskComponent;
419
420    /**
421     * For addAppTask: cached of the last activity uid that was added.
422     */
423    int mLastAddedTaskUid;
424
425    /**
426     * For addAppTask: cached of the last ActivityInfo that was added.
427     */
428    ActivityInfo mLastAddedTaskActivity;
429
430    public class PendingAssistExtras extends Binder implements Runnable {
431        public final ActivityRecord activity;
432        public boolean haveResult = false;
433        public Bundle result = null;
434        public PendingAssistExtras(ActivityRecord _activity) {
435            activity = _activity;
436        }
437        @Override
438        public void run() {
439            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
440            synchronized (this) {
441                haveResult = true;
442                notifyAll();
443            }
444        }
445    }
446
447    final ArrayList<PendingAssistExtras> mPendingAssistExtras
448            = new ArrayList<PendingAssistExtras>();
449
450    /**
451     * Process management.
452     */
453    final ProcessList mProcessList = new ProcessList();
454
455    /**
456     * All of the applications we currently have running organized by name.
457     * The keys are strings of the application package name (as
458     * returned by the package manager), and the keys are ApplicationRecord
459     * objects.
460     */
461    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
462
463    /**
464     * Tracking long-term execution of processes to look for abuse and other
465     * bad app behavior.
466     */
467    final ProcessStatsService mProcessStats;
468
469    /**
470     * The currently running isolated processes.
471     */
472    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
473
474    /**
475     * Counter for assigning isolated process uids, to avoid frequently reusing the
476     * same ones.
477     */
478    int mNextIsolatedProcessUid = 0;
479
480    /**
481     * The currently running heavy-weight process, if any.
482     */
483    ProcessRecord mHeavyWeightProcess = null;
484
485    /**
486     * The last time that various processes have crashed.
487     */
488    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
489
490    /**
491     * Information about a process that is currently marked as bad.
492     */
493    static final class BadProcessInfo {
494        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
495            this.time = time;
496            this.shortMsg = shortMsg;
497            this.longMsg = longMsg;
498            this.stack = stack;
499        }
500
501        final long time;
502        final String shortMsg;
503        final String longMsg;
504        final String stack;
505    }
506
507    /**
508     * Set of applications that we consider to be bad, and will reject
509     * incoming broadcasts from (which the user has no control over).
510     * Processes are added to this set when they have crashed twice within
511     * a minimum amount of time; they are removed from it when they are
512     * later restarted (hopefully due to some user action).  The value is the
513     * time it was added to the list.
514     */
515    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
516
517    /**
518     * All of the processes we currently have running organized by pid.
519     * The keys are the pid running the application.
520     *
521     * <p>NOTE: This object is protected by its own lock, NOT the global
522     * activity manager lock!
523     */
524    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
525
526    /**
527     * All of the processes that have been forced to be foreground.  The key
528     * is the pid of the caller who requested it (we hold a death
529     * link on it).
530     */
531    abstract class ForegroundToken implements IBinder.DeathRecipient {
532        int pid;
533        IBinder token;
534    }
535    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
536
537    /**
538     * List of records for processes that someone had tried to start before the
539     * system was ready.  We don't start them at that point, but ensure they
540     * are started by the time booting is complete.
541     */
542    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
543
544    /**
545     * List of persistent applications that are in the process
546     * of being started.
547     */
548    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
549
550    /**
551     * Processes that are being forcibly torn down.
552     */
553    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
554
555    /**
556     * List of running applications, sorted by recent usage.
557     * The first entry in the list is the least recently used.
558     */
559    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
560
561    /**
562     * Where in mLruProcesses that the processes hosting activities start.
563     */
564    int mLruProcessActivityStart = 0;
565
566    /**
567     * Where in mLruProcesses that the processes hosting services start.
568     * This is after (lower index) than mLruProcessesActivityStart.
569     */
570    int mLruProcessServiceStart = 0;
571
572    /**
573     * List of processes that should gc as soon as things are idle.
574     */
575    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
576
577    /**
578     * Processes we want to collect PSS data from.
579     */
580    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
581
582    /**
583     * Last time we requested PSS data of all processes.
584     */
585    long mLastFullPssTime = SystemClock.uptimeMillis();
586
587    /**
588     * If set, the next time we collect PSS data we should do a full collection
589     * with data from native processes and the kernel.
590     */
591    boolean mFullPssPending = false;
592
593    /**
594     * This is the process holding what we currently consider to be
595     * the "home" activity.
596     */
597    ProcessRecord mHomeProcess;
598
599    /**
600     * This is the process holding the activity the user last visited that
601     * is in a different process from the one they are currently in.
602     */
603    ProcessRecord mPreviousProcess;
604
605    /**
606     * The time at which the previous process was last visible.
607     */
608    long mPreviousProcessVisibleTime;
609
610    /**
611     * Which uses have been started, so are allowed to run code.
612     */
613    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
614
615    /**
616     * LRU list of history of current users.  Most recently current is at the end.
617     */
618    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
619
620    /**
621     * Constant array of the users that are currently started.
622     */
623    int[] mStartedUserArray = new int[] { 0 };
624
625    /**
626     * Registered observers of the user switching mechanics.
627     */
628    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
629            = new RemoteCallbackList<IUserSwitchObserver>();
630
631    /**
632     * Currently active user switch.
633     */
634    Object mCurUserSwitchCallback;
635
636    /**
637     * Packages that the user has asked to have run in screen size
638     * compatibility mode instead of filling the screen.
639     */
640    final CompatModePackages mCompatModePackages;
641
642    /**
643     * Set of IntentSenderRecord objects that are currently active.
644     */
645    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
646            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
647
648    /**
649     * Fingerprints (hashCode()) of stack traces that we've
650     * already logged DropBox entries for.  Guarded by itself.  If
651     * something (rogue user app) forces this over
652     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
653     */
654    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
655    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
656
657    /**
658     * Strict Mode background batched logging state.
659     *
660     * The string buffer is guarded by itself, and its lock is also
661     * used to determine if another batched write is already
662     * in-flight.
663     */
664    private final StringBuilder mStrictModeBuffer = new StringBuilder();
665
666    /**
667     * Keeps track of all IIntentReceivers that have been registered for
668     * broadcasts.  Hash keys are the receiver IBinder, hash value is
669     * a ReceiverList.
670     */
671    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
672            new HashMap<IBinder, ReceiverList>();
673
674    /**
675     * Resolver for broadcast intents to registered receivers.
676     * Holds BroadcastFilter (subclass of IntentFilter).
677     */
678    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
679            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
680        @Override
681        protected boolean allowFilterResult(
682                BroadcastFilter filter, List<BroadcastFilter> dest) {
683            IBinder target = filter.receiverList.receiver.asBinder();
684            for (int i=dest.size()-1; i>=0; i--) {
685                if (dest.get(i).receiverList.receiver.asBinder() == target) {
686                    return false;
687                }
688            }
689            return true;
690        }
691
692        @Override
693        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
694            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
695                    || userId == filter.owningUserId) {
696                return super.newResult(filter, match, userId);
697            }
698            return null;
699        }
700
701        @Override
702        protected BroadcastFilter[] newArray(int size) {
703            return new BroadcastFilter[size];
704        }
705
706        @Override
707        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
708            return packageName.equals(filter.packageName);
709        }
710    };
711
712    /**
713     * State of all active sticky broadcasts per user.  Keys are the action of the
714     * sticky Intent, values are an ArrayList of all broadcasted intents with
715     * that action (which should usually be one).  The SparseArray is keyed
716     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
717     * for stickies that are sent to all users.
718     */
719    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
720            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
721
722    final ActiveServices mServices;
723
724    /**
725     * Backup/restore process management
726     */
727    String mBackupAppName = null;
728    BackupRecord mBackupTarget = null;
729
730    final ProviderMap mProviderMap;
731
732    /**
733     * List of content providers who have clients waiting for them.  The
734     * application is currently being launched and the provider will be
735     * removed from this list once it is published.
736     */
737    final ArrayList<ContentProviderRecord> mLaunchingProviders
738            = new ArrayList<ContentProviderRecord>();
739
740    /**
741     * File storing persisted {@link #mGrantedUriPermissions}.
742     */
743    private final AtomicFile mGrantFile;
744
745    /** XML constants used in {@link #mGrantFile} */
746    private static final String TAG_URI_GRANTS = "uri-grants";
747    private static final String TAG_URI_GRANT = "uri-grant";
748    private static final String ATTR_USER_HANDLE = "userHandle";
749    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
750    private static final String ATTR_TARGET_USER_ID = "targetUserId";
751    private static final String ATTR_SOURCE_PKG = "sourcePkg";
752    private static final String ATTR_TARGET_PKG = "targetPkg";
753    private static final String ATTR_URI = "uri";
754    private static final String ATTR_MODE_FLAGS = "modeFlags";
755    private static final String ATTR_CREATED_TIME = "createdTime";
756    private static final String ATTR_PREFIX = "prefix";
757
758    /**
759     * Global set of specific {@link Uri} permissions that have been granted.
760     * This optimized lookup structure maps from {@link UriPermission#targetUid}
761     * to {@link UriPermission#uri} to {@link UriPermission}.
762     */
763    @GuardedBy("this")
764    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
765            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
766
767    public static class GrantUri {
768        public final int sourceUserId;
769        public final Uri uri;
770        public boolean prefix;
771
772        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
773            this.sourceUserId = sourceUserId;
774            this.uri = uri;
775            this.prefix = prefix;
776        }
777
778        @Override
779        public int hashCode() {
780            return toString().hashCode();
781        }
782
783        @Override
784        public boolean equals(Object o) {
785            if (o instanceof GrantUri) {
786                GrantUri other = (GrantUri) o;
787                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
788                        && prefix == other.prefix;
789            }
790            return false;
791        }
792
793        @Override
794        public String toString() {
795            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
796            if (prefix) result += " [prefix]";
797            return result;
798        }
799
800        public String toSafeString() {
801            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
802            if (prefix) result += " [prefix]";
803            return result;
804        }
805
806        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
807            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
808                    ContentProvider.getUriWithoutUserId(uri), false);
809        }
810    }
811
812    CoreSettingsObserver mCoreSettingsObserver;
813
814    /**
815     * Thread-local storage used to carry caller permissions over through
816     * indirect content-provider access.
817     */
818    private class Identity {
819        public int pid;
820        public int uid;
821
822        Identity(int _pid, int _uid) {
823            pid = _pid;
824            uid = _uid;
825        }
826    }
827
828    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
829
830    /**
831     * All information we have collected about the runtime performance of
832     * any user id that can impact battery performance.
833     */
834    final BatteryStatsService mBatteryStatsService;
835
836    /**
837     * Information about component usage
838     */
839    UsageStatsManagerInternal mUsageStatsService;
840
841    /**
842     * Information about and control over application operations
843     */
844    final AppOpsService mAppOpsService;
845
846    /**
847     * Save recent tasks information across reboots.
848     */
849    final TaskPersister mTaskPersister;
850
851    /**
852     * Current configuration information.  HistoryRecord objects are given
853     * a reference to this object to indicate which configuration they are
854     * currently running in, so this object must be kept immutable.
855     */
856    Configuration mConfiguration = new Configuration();
857
858    /**
859     * Current sequencing integer of the configuration, for skipping old
860     * configurations.
861     */
862    int mConfigurationSeq = 0;
863
864    /**
865     * Hardware-reported OpenGLES version.
866     */
867    final int GL_ES_VERSION;
868
869    /**
870     * List of initialization arguments to pass to all processes when binding applications to them.
871     * For example, references to the commonly used services.
872     */
873    HashMap<String, IBinder> mAppBindArgs;
874
875    /**
876     * Temporary to avoid allocations.  Protected by main lock.
877     */
878    final StringBuilder mStringBuilder = new StringBuilder(256);
879
880    /**
881     * Used to control how we initialize the service.
882     */
883    ComponentName mTopComponent;
884    String mTopAction = Intent.ACTION_MAIN;
885    String mTopData;
886    boolean mProcessesReady = false;
887    boolean mSystemReady = false;
888    boolean mBooting = false;
889    boolean mWaitingUpdate = false;
890    boolean mDidUpdate = false;
891    boolean mOnBattery = false;
892    boolean mLaunchWarningShown = false;
893
894    Context mContext;
895
896    int mFactoryTest;
897
898    boolean mCheckedForSetup;
899
900    /**
901     * The time at which we will allow normal application switches again,
902     * after a call to {@link #stopAppSwitches()}.
903     */
904    long mAppSwitchesAllowedTime;
905
906    /**
907     * This is set to true after the first switch after mAppSwitchesAllowedTime
908     * is set; any switches after that will clear the time.
909     */
910    boolean mDidAppSwitch;
911
912    /**
913     * Last time (in realtime) at which we checked for power usage.
914     */
915    long mLastPowerCheckRealtime;
916
917    /**
918     * Last time (in uptime) at which we checked for power usage.
919     */
920    long mLastPowerCheckUptime;
921
922    /**
923     * Set while we are wanting to sleep, to prevent any
924     * activities from being started/resumed.
925     */
926    private boolean mSleeping = false;
927
928    /**
929     * Set while we are running a voice interaction.  This overrides
930     * sleeping while it is active.
931     */
932    private boolean mRunningVoice = false;
933
934    /**
935     * State of external calls telling us if the device is asleep.
936     */
937    private boolean mWentToSleep = false;
938
939    /**
940     * State of external call telling us if the lock screen is shown.
941     */
942    private boolean mLockScreenShown = false;
943
944    /**
945     * Set if we are shutting down the system, similar to sleeping.
946     */
947    boolean mShuttingDown = false;
948
949    /**
950     * Current sequence id for oom_adj computation traversal.
951     */
952    int mAdjSeq = 0;
953
954    /**
955     * Current sequence id for process LRU updating.
956     */
957    int mLruSeq = 0;
958
959    /**
960     * Keep track of the non-cached/empty process we last found, to help
961     * determine how to distribute cached/empty processes next time.
962     */
963    int mNumNonCachedProcs = 0;
964
965    /**
966     * Keep track of the number of cached hidden procs, to balance oom adj
967     * distribution between those and empty procs.
968     */
969    int mNumCachedHiddenProcs = 0;
970
971    /**
972     * Keep track of the number of service processes we last found, to
973     * determine on the next iteration which should be B services.
974     */
975    int mNumServiceProcs = 0;
976    int mNewNumAServiceProcs = 0;
977    int mNewNumServiceProcs = 0;
978
979    /**
980     * Allow the current computed overall memory level of the system to go down?
981     * This is set to false when we are killing processes for reasons other than
982     * memory management, so that the now smaller process list will not be taken as
983     * an indication that memory is tighter.
984     */
985    boolean mAllowLowerMemLevel = false;
986
987    /**
988     * The last computed memory level, for holding when we are in a state that
989     * processes are going away for other reasons.
990     */
991    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
992
993    /**
994     * The last total number of process we have, to determine if changes actually look
995     * like a shrinking number of process due to lower RAM.
996     */
997    int mLastNumProcesses;
998
999    /**
1000     * The uptime of the last time we performed idle maintenance.
1001     */
1002    long mLastIdleTime = SystemClock.uptimeMillis();
1003
1004    /**
1005     * Total time spent with RAM that has been added in the past since the last idle time.
1006     */
1007    long mLowRamTimeSinceLastIdle = 0;
1008
1009    /**
1010     * If RAM is currently low, when that horrible situation started.
1011     */
1012    long mLowRamStartTime = 0;
1013
1014    /**
1015     * For reporting to battery stats the current top application.
1016     */
1017    private String mCurResumedPackage = null;
1018    private int mCurResumedUid = -1;
1019
1020    /**
1021     * For reporting to battery stats the apps currently running foreground
1022     * service.  The ProcessMap is package/uid tuples; each of these contain
1023     * an array of the currently foreground processes.
1024     */
1025    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1026            = new ProcessMap<ArrayList<ProcessRecord>>();
1027
1028    /**
1029     * This is set if we had to do a delayed dexopt of an app before launching
1030     * it, to increase the ANR timeouts in that case.
1031     */
1032    boolean mDidDexOpt;
1033
1034    /**
1035     * Set if the systemServer made a call to enterSafeMode.
1036     */
1037    boolean mSafeMode;
1038
1039    String mDebugApp = null;
1040    boolean mWaitForDebugger = false;
1041    boolean mDebugTransient = false;
1042    String mOrigDebugApp = null;
1043    boolean mOrigWaitForDebugger = false;
1044    boolean mAlwaysFinishActivities = false;
1045    IActivityController mController = null;
1046    String mProfileApp = null;
1047    ProcessRecord mProfileProc = null;
1048    String mProfileFile;
1049    ParcelFileDescriptor mProfileFd;
1050    int mProfileType = 0;
1051    boolean mAutoStopProfiler = false;
1052    String mOpenGlTraceApp = null;
1053
1054    static class ProcessChangeItem {
1055        static final int CHANGE_ACTIVITIES = 1<<0;
1056        static final int CHANGE_PROCESS_STATE = 1<<1;
1057        int changes;
1058        int uid;
1059        int pid;
1060        int processState;
1061        boolean foregroundActivities;
1062    }
1063
1064    final RemoteCallbackList<IProcessObserver> mProcessObservers
1065            = new RemoteCallbackList<IProcessObserver>();
1066    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1067
1068    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1069            = new ArrayList<ProcessChangeItem>();
1070    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1071            = new ArrayList<ProcessChangeItem>();
1072
1073    /**
1074     * Runtime CPU use collection thread.  This object's lock is used to
1075     * protect all related state.
1076     */
1077    final Thread mProcessCpuThread;
1078
1079    /**
1080     * Used to collect process stats when showing not responding dialog.
1081     * Protected by mProcessCpuThread.
1082     */
1083    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1084            MONITOR_THREAD_CPU_USAGE);
1085    final AtomicLong mLastCpuTime = new AtomicLong(0);
1086    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1087
1088    long mLastWriteTime = 0;
1089
1090    /**
1091     * Used to retain an update lock when the foreground activity is in
1092     * immersive mode.
1093     */
1094    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1095
1096    /**
1097     * Set to true after the system has finished booting.
1098     */
1099    boolean mBooted = false;
1100
1101    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1102    int mProcessLimitOverride = -1;
1103
1104    WindowManagerService mWindowManager;
1105
1106    final ActivityThread mSystemThread;
1107
1108    int mCurrentUserId = 0;
1109    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1110
1111    /**
1112     * Mapping from each known user ID to the profile group ID it is associated with.
1113     */
1114    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1115
1116    private UserManagerService mUserManager;
1117
1118    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1119        final ProcessRecord mApp;
1120        final int mPid;
1121        final IApplicationThread mAppThread;
1122
1123        AppDeathRecipient(ProcessRecord app, int pid,
1124                IApplicationThread thread) {
1125            if (localLOGV) Slog.v(
1126                TAG, "New death recipient " + this
1127                + " for thread " + thread.asBinder());
1128            mApp = app;
1129            mPid = pid;
1130            mAppThread = thread;
1131        }
1132
1133        @Override
1134        public void binderDied() {
1135            if (localLOGV) Slog.v(
1136                TAG, "Death received in " + this
1137                + " for thread " + mAppThread.asBinder());
1138            synchronized(ActivityManagerService.this) {
1139                appDiedLocked(mApp, mPid, mAppThread);
1140            }
1141        }
1142    }
1143
1144    static final int SHOW_ERROR_MSG = 1;
1145    static final int SHOW_NOT_RESPONDING_MSG = 2;
1146    static final int SHOW_FACTORY_ERROR_MSG = 3;
1147    static final int UPDATE_CONFIGURATION_MSG = 4;
1148    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1149    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1150    static final int SERVICE_TIMEOUT_MSG = 12;
1151    static final int UPDATE_TIME_ZONE = 13;
1152    static final int SHOW_UID_ERROR_MSG = 14;
1153    static final int IM_FEELING_LUCKY_MSG = 15;
1154    static final int PROC_START_TIMEOUT_MSG = 20;
1155    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1156    static final int KILL_APPLICATION_MSG = 22;
1157    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1158    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1159    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1160    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1161    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1162    static final int CLEAR_DNS_CACHE_MSG = 28;
1163    static final int UPDATE_HTTP_PROXY_MSG = 29;
1164    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1165    static final int DISPATCH_PROCESSES_CHANGED = 31;
1166    static final int DISPATCH_PROCESS_DIED = 32;
1167    static final int REPORT_MEM_USAGE_MSG = 33;
1168    static final int REPORT_USER_SWITCH_MSG = 34;
1169    static final int CONTINUE_USER_SWITCH_MSG = 35;
1170    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1171    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1172    static final int PERSIST_URI_GRANTS_MSG = 38;
1173    static final int REQUEST_ALL_PSS_MSG = 39;
1174    static final int START_PROFILES_MSG = 40;
1175    static final int UPDATE_TIME = 41;
1176    static final int SYSTEM_USER_START_MSG = 42;
1177    static final int SYSTEM_USER_CURRENT_MSG = 43;
1178    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1179    static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45;
1180    static final int START_USER_SWITCH_MSG = 46;
1181
1182    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1183    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1184    static final int FIRST_COMPAT_MODE_MSG = 300;
1185    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1186
1187    AlertDialog mUidAlert;
1188    CompatModeDialog mCompatModeDialog;
1189    long mLastMemUsageReportTime = 0;
1190
1191    private LockToAppRequestDialog mLockToAppRequest;
1192
1193    /**
1194     * Flag whether the current user is a "monkey", i.e. whether
1195     * the UI is driven by a UI automation tool.
1196     */
1197    private boolean mUserIsMonkey;
1198
1199    /** Flag whether the device has a recents UI */
1200    final boolean mHasRecents;
1201
1202    final int mThumbnailWidth;
1203    final int mThumbnailHeight;
1204
1205    final ServiceThread mHandlerThread;
1206    final MainHandler mHandler;
1207
1208    final class MainHandler extends Handler {
1209        public MainHandler(Looper looper) {
1210            super(looper, null, true);
1211        }
1212
1213        @Override
1214        public void handleMessage(Message msg) {
1215            switch (msg.what) {
1216            case SHOW_ERROR_MSG: {
1217                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1218                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1219                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1220                synchronized (ActivityManagerService.this) {
1221                    ProcessRecord proc = (ProcessRecord)data.get("app");
1222                    AppErrorResult res = (AppErrorResult) data.get("result");
1223                    if (proc != null && proc.crashDialog != null) {
1224                        Slog.e(TAG, "App already has crash dialog: " + proc);
1225                        if (res != null) {
1226                            res.set(0);
1227                        }
1228                        return;
1229                    }
1230                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1231                            >= Process.FIRST_APPLICATION_UID
1232                            && proc.pid != MY_PID);
1233                    for (int userId : mCurrentProfileIds) {
1234                        isBackground &= (proc.userId != userId);
1235                    }
1236                    if (isBackground && !showBackground) {
1237                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1238                        if (res != null) {
1239                            res.set(0);
1240                        }
1241                        return;
1242                    }
1243                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1244                        Dialog d = new AppErrorDialog(mContext,
1245                                ActivityManagerService.this, res, proc);
1246                        d.show();
1247                        proc.crashDialog = d;
1248                    } else {
1249                        // The device is asleep, so just pretend that the user
1250                        // saw a crash dialog and hit "force quit".
1251                        if (res != null) {
1252                            res.set(0);
1253                        }
1254                    }
1255                }
1256
1257                ensureBootCompleted();
1258            } break;
1259            case SHOW_NOT_RESPONDING_MSG: {
1260                synchronized (ActivityManagerService.this) {
1261                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1262                    ProcessRecord proc = (ProcessRecord)data.get("app");
1263                    if (proc != null && proc.anrDialog != null) {
1264                        Slog.e(TAG, "App already has anr dialog: " + proc);
1265                        return;
1266                    }
1267
1268                    Intent intent = new Intent("android.intent.action.ANR");
1269                    if (!mProcessesReady) {
1270                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1271                                | Intent.FLAG_RECEIVER_FOREGROUND);
1272                    }
1273                    broadcastIntentLocked(null, null, intent,
1274                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1275                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1276
1277                    if (mShowDialogs) {
1278                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1279                                mContext, proc, (ActivityRecord)data.get("activity"),
1280                                msg.arg1 != 0);
1281                        d.show();
1282                        proc.anrDialog = d;
1283                    } else {
1284                        // Just kill the app if there is no dialog to be shown.
1285                        killAppAtUsersRequest(proc, null);
1286                    }
1287                }
1288
1289                ensureBootCompleted();
1290            } break;
1291            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1292                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1293                synchronized (ActivityManagerService.this) {
1294                    ProcessRecord proc = (ProcessRecord) data.get("app");
1295                    if (proc == null) {
1296                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1297                        break;
1298                    }
1299                    if (proc.crashDialog != null) {
1300                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1301                        return;
1302                    }
1303                    AppErrorResult res = (AppErrorResult) data.get("result");
1304                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1305                        Dialog d = new StrictModeViolationDialog(mContext,
1306                                ActivityManagerService.this, res, proc);
1307                        d.show();
1308                        proc.crashDialog = d;
1309                    } else {
1310                        // The device is asleep, so just pretend that the user
1311                        // saw a crash dialog and hit "force quit".
1312                        res.set(0);
1313                    }
1314                }
1315                ensureBootCompleted();
1316            } break;
1317            case SHOW_FACTORY_ERROR_MSG: {
1318                Dialog d = new FactoryErrorDialog(
1319                    mContext, msg.getData().getCharSequence("msg"));
1320                d.show();
1321                ensureBootCompleted();
1322            } break;
1323            case UPDATE_CONFIGURATION_MSG: {
1324                final ContentResolver resolver = mContext.getContentResolver();
1325                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1326            } break;
1327            case GC_BACKGROUND_PROCESSES_MSG: {
1328                synchronized (ActivityManagerService.this) {
1329                    performAppGcsIfAppropriateLocked();
1330                }
1331            } break;
1332            case WAIT_FOR_DEBUGGER_MSG: {
1333                synchronized (ActivityManagerService.this) {
1334                    ProcessRecord app = (ProcessRecord)msg.obj;
1335                    if (msg.arg1 != 0) {
1336                        if (!app.waitedForDebugger) {
1337                            Dialog d = new AppWaitingForDebuggerDialog(
1338                                    ActivityManagerService.this,
1339                                    mContext, app);
1340                            app.waitDialog = d;
1341                            app.waitedForDebugger = true;
1342                            d.show();
1343                        }
1344                    } else {
1345                        if (app.waitDialog != null) {
1346                            app.waitDialog.dismiss();
1347                            app.waitDialog = null;
1348                        }
1349                    }
1350                }
1351            } break;
1352            case SERVICE_TIMEOUT_MSG: {
1353                if (mDidDexOpt) {
1354                    mDidDexOpt = false;
1355                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1356                    nmsg.obj = msg.obj;
1357                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1358                    return;
1359                }
1360                mServices.serviceTimeout((ProcessRecord)msg.obj);
1361            } break;
1362            case UPDATE_TIME_ZONE: {
1363                synchronized (ActivityManagerService.this) {
1364                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1365                        ProcessRecord r = mLruProcesses.get(i);
1366                        if (r.thread != null) {
1367                            try {
1368                                r.thread.updateTimeZone();
1369                            } catch (RemoteException ex) {
1370                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1371                            }
1372                        }
1373                    }
1374                }
1375            } break;
1376            case CLEAR_DNS_CACHE_MSG: {
1377                synchronized (ActivityManagerService.this) {
1378                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1379                        ProcessRecord r = mLruProcesses.get(i);
1380                        if (r.thread != null) {
1381                            try {
1382                                r.thread.clearDnsCache();
1383                            } catch (RemoteException ex) {
1384                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1385                            }
1386                        }
1387                    }
1388                }
1389            } break;
1390            case UPDATE_HTTP_PROXY_MSG: {
1391                ProxyInfo proxy = (ProxyInfo)msg.obj;
1392                String host = "";
1393                String port = "";
1394                String exclList = "";
1395                Uri pacFileUrl = Uri.EMPTY;
1396                if (proxy != null) {
1397                    host = proxy.getHost();
1398                    port = Integer.toString(proxy.getPort());
1399                    exclList = proxy.getExclusionListAsString();
1400                    pacFileUrl = proxy.getPacFileUrl();
1401                }
1402                synchronized (ActivityManagerService.this) {
1403                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1404                        ProcessRecord r = mLruProcesses.get(i);
1405                        if (r.thread != null) {
1406                            try {
1407                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1408                            } catch (RemoteException ex) {
1409                                Slog.w(TAG, "Failed to update http proxy for: " +
1410                                        r.info.processName);
1411                            }
1412                        }
1413                    }
1414                }
1415            } break;
1416            case SHOW_UID_ERROR_MSG: {
1417                String title = "System UIDs Inconsistent";
1418                String text = "UIDs on the system are inconsistent, you need to wipe your"
1419                        + " data partition or your device will be unstable.";
1420                Log.e(TAG, title + ": " + text);
1421                if (mShowDialogs) {
1422                    // XXX This is a temporary dialog, no need to localize.
1423                    AlertDialog d = new BaseErrorDialog(mContext);
1424                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1425                    d.setCancelable(false);
1426                    d.setTitle(title);
1427                    d.setMessage(text);
1428                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1429                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1430                    mUidAlert = d;
1431                    d.show();
1432                }
1433            } break;
1434            case IM_FEELING_LUCKY_MSG: {
1435                if (mUidAlert != null) {
1436                    mUidAlert.dismiss();
1437                    mUidAlert = null;
1438                }
1439            } break;
1440            case PROC_START_TIMEOUT_MSG: {
1441                if (mDidDexOpt) {
1442                    mDidDexOpt = false;
1443                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1444                    nmsg.obj = msg.obj;
1445                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1446                    return;
1447                }
1448                ProcessRecord app = (ProcessRecord)msg.obj;
1449                synchronized (ActivityManagerService.this) {
1450                    processStartTimedOutLocked(app);
1451                }
1452            } break;
1453            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1454                synchronized (ActivityManagerService.this) {
1455                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1456                }
1457            } break;
1458            case KILL_APPLICATION_MSG: {
1459                synchronized (ActivityManagerService.this) {
1460                    int appid = msg.arg1;
1461                    boolean restart = (msg.arg2 == 1);
1462                    Bundle bundle = (Bundle)msg.obj;
1463                    String pkg = bundle.getString("pkg");
1464                    String reason = bundle.getString("reason");
1465                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1466                            false, UserHandle.USER_ALL, reason);
1467                }
1468            } break;
1469            case FINALIZE_PENDING_INTENT_MSG: {
1470                ((PendingIntentRecord)msg.obj).completeFinalize();
1471            } break;
1472            case POST_HEAVY_NOTIFICATION_MSG: {
1473                INotificationManager inm = NotificationManager.getService();
1474                if (inm == null) {
1475                    return;
1476                }
1477
1478                ActivityRecord root = (ActivityRecord)msg.obj;
1479                ProcessRecord process = root.app;
1480                if (process == null) {
1481                    return;
1482                }
1483
1484                try {
1485                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1486                    String text = mContext.getString(R.string.heavy_weight_notification,
1487                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1488                    Notification notification = new Notification();
1489                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1490                    notification.when = 0;
1491                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1492                    notification.tickerText = text;
1493                    notification.defaults = 0; // please be quiet
1494                    notification.sound = null;
1495                    notification.vibrate = null;
1496                    notification.color = mContext.getResources().getColor(
1497                            com.android.internal.R.color.system_notification_accent_color);
1498                    notification.setLatestEventInfo(context, text,
1499                            mContext.getText(R.string.heavy_weight_notification_detail),
1500                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1501                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1502                                    new UserHandle(root.userId)));
1503
1504                    try {
1505                        int[] outId = new int[1];
1506                        inm.enqueueNotificationWithTag("android", "android", null,
1507                                R.string.heavy_weight_notification,
1508                                notification, outId, root.userId);
1509                    } catch (RuntimeException e) {
1510                        Slog.w(ActivityManagerService.TAG,
1511                                "Error showing notification for heavy-weight app", e);
1512                    } catch (RemoteException e) {
1513                    }
1514                } catch (NameNotFoundException e) {
1515                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1516                }
1517            } break;
1518            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1519                INotificationManager inm = NotificationManager.getService();
1520                if (inm == null) {
1521                    return;
1522                }
1523                try {
1524                    inm.cancelNotificationWithTag("android", null,
1525                            R.string.heavy_weight_notification,  msg.arg1);
1526                } catch (RuntimeException e) {
1527                    Slog.w(ActivityManagerService.TAG,
1528                            "Error canceling notification for service", e);
1529                } catch (RemoteException e) {
1530                }
1531            } break;
1532            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1533                synchronized (ActivityManagerService.this) {
1534                    checkExcessivePowerUsageLocked(true);
1535                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1536                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1537                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1538                }
1539            } break;
1540            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1541                synchronized (ActivityManagerService.this) {
1542                    ActivityRecord ar = (ActivityRecord)msg.obj;
1543                    if (mCompatModeDialog != null) {
1544                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1545                                ar.info.applicationInfo.packageName)) {
1546                            return;
1547                        }
1548                        mCompatModeDialog.dismiss();
1549                        mCompatModeDialog = null;
1550                    }
1551                    if (ar != null && false) {
1552                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1553                                ar.packageName)) {
1554                            int mode = mCompatModePackages.computeCompatModeLocked(
1555                                    ar.info.applicationInfo);
1556                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1557                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1558                                mCompatModeDialog = new CompatModeDialog(
1559                                        ActivityManagerService.this, mContext,
1560                                        ar.info.applicationInfo);
1561                                mCompatModeDialog.show();
1562                            }
1563                        }
1564                    }
1565                }
1566                break;
1567            }
1568            case DISPATCH_PROCESSES_CHANGED: {
1569                dispatchProcessesChanged();
1570                break;
1571            }
1572            case DISPATCH_PROCESS_DIED: {
1573                final int pid = msg.arg1;
1574                final int uid = msg.arg2;
1575                dispatchProcessDied(pid, uid);
1576                break;
1577            }
1578            case REPORT_MEM_USAGE_MSG: {
1579                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1580                Thread thread = new Thread() {
1581                    @Override public void run() {
1582                        final SparseArray<ProcessMemInfo> infoMap
1583                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1584                        for (int i=0, N=memInfos.size(); i<N; i++) {
1585                            ProcessMemInfo mi = memInfos.get(i);
1586                            infoMap.put(mi.pid, mi);
1587                        }
1588                        updateCpuStatsNow();
1589                        synchronized (mProcessCpuThread) {
1590                            final int N = mProcessCpuTracker.countStats();
1591                            for (int i=0; i<N; i++) {
1592                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1593                                if (st.vsize > 0) {
1594                                    long pss = Debug.getPss(st.pid, null);
1595                                    if (pss > 0) {
1596                                        if (infoMap.indexOfKey(st.pid) < 0) {
1597                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1598                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1599                                            mi.pss = pss;
1600                                            memInfos.add(mi);
1601                                        }
1602                                    }
1603                                }
1604                            }
1605                        }
1606
1607                        long totalPss = 0;
1608                        for (int i=0, N=memInfos.size(); i<N; i++) {
1609                            ProcessMemInfo mi = memInfos.get(i);
1610                            if (mi.pss == 0) {
1611                                mi.pss = Debug.getPss(mi.pid, null);
1612                            }
1613                            totalPss += mi.pss;
1614                        }
1615                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1616                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1617                                if (lhs.oomAdj != rhs.oomAdj) {
1618                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1619                                }
1620                                if (lhs.pss != rhs.pss) {
1621                                    return lhs.pss < rhs.pss ? 1 : -1;
1622                                }
1623                                return 0;
1624                            }
1625                        });
1626
1627                        StringBuilder tag = new StringBuilder(128);
1628                        StringBuilder stack = new StringBuilder(128);
1629                        tag.append("Low on memory -- ");
1630                        appendMemBucket(tag, totalPss, "total", false);
1631                        appendMemBucket(stack, totalPss, "total", true);
1632
1633                        StringBuilder logBuilder = new StringBuilder(1024);
1634                        logBuilder.append("Low on memory:\n");
1635
1636                        boolean firstLine = true;
1637                        int lastOomAdj = Integer.MIN_VALUE;
1638                        for (int i=0, N=memInfos.size(); i<N; i++) {
1639                            ProcessMemInfo mi = memInfos.get(i);
1640
1641                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1642                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1643                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1644                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1645                                if (lastOomAdj != mi.oomAdj) {
1646                                    lastOomAdj = mi.oomAdj;
1647                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1648                                        tag.append(" / ");
1649                                    }
1650                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1651                                        if (firstLine) {
1652                                            stack.append(":");
1653                                            firstLine = false;
1654                                        }
1655                                        stack.append("\n\t at ");
1656                                    } else {
1657                                        stack.append("$");
1658                                    }
1659                                } else {
1660                                    tag.append(" ");
1661                                    stack.append("$");
1662                                }
1663                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1664                                    appendMemBucket(tag, mi.pss, mi.name, false);
1665                                }
1666                                appendMemBucket(stack, mi.pss, mi.name, true);
1667                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1668                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1669                                    stack.append("(");
1670                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1671                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1672                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1673                                            stack.append(":");
1674                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1675                                        }
1676                                    }
1677                                    stack.append(")");
1678                                }
1679                            }
1680
1681                            logBuilder.append("  ");
1682                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1683                            logBuilder.append(' ');
1684                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1685                            logBuilder.append(' ');
1686                            ProcessList.appendRamKb(logBuilder, mi.pss);
1687                            logBuilder.append(" kB: ");
1688                            logBuilder.append(mi.name);
1689                            logBuilder.append(" (");
1690                            logBuilder.append(mi.pid);
1691                            logBuilder.append(") ");
1692                            logBuilder.append(mi.adjType);
1693                            logBuilder.append('\n');
1694                            if (mi.adjReason != null) {
1695                                logBuilder.append("                      ");
1696                                logBuilder.append(mi.adjReason);
1697                                logBuilder.append('\n');
1698                            }
1699                        }
1700
1701                        logBuilder.append("           ");
1702                        ProcessList.appendRamKb(logBuilder, totalPss);
1703                        logBuilder.append(" kB: TOTAL\n");
1704
1705                        long[] infos = new long[Debug.MEMINFO_COUNT];
1706                        Debug.getMemInfo(infos);
1707                        logBuilder.append("  MemInfo: ");
1708                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1709                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1710                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1711                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1712                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1713                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1714                            logBuilder.append("  ZRAM: ");
1715                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1716                            logBuilder.append(" kB RAM, ");
1717                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1718                            logBuilder.append(" kB swap total, ");
1719                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1720                            logBuilder.append(" kB swap free\n");
1721                        }
1722                        Slog.i(TAG, logBuilder.toString());
1723
1724                        StringBuilder dropBuilder = new StringBuilder(1024);
1725                        /*
1726                        StringWriter oomSw = new StringWriter();
1727                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1728                        StringWriter catSw = new StringWriter();
1729                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1730                        String[] emptyArgs = new String[] { };
1731                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1732                        oomPw.flush();
1733                        String oomString = oomSw.toString();
1734                        */
1735                        dropBuilder.append(stack);
1736                        dropBuilder.append('\n');
1737                        dropBuilder.append('\n');
1738                        dropBuilder.append(logBuilder);
1739                        dropBuilder.append('\n');
1740                        /*
1741                        dropBuilder.append(oomString);
1742                        dropBuilder.append('\n');
1743                        */
1744                        StringWriter catSw = new StringWriter();
1745                        synchronized (ActivityManagerService.this) {
1746                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1747                            String[] emptyArgs = new String[] { };
1748                            catPw.println();
1749                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1750                            catPw.println();
1751                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1752                                    false, false, null);
1753                            catPw.println();
1754                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1755                            catPw.flush();
1756                        }
1757                        dropBuilder.append(catSw.toString());
1758                        addErrorToDropBox("lowmem", null, "system_server", null,
1759                                null, tag.toString(), dropBuilder.toString(), null, null);
1760                        //Slog.i(TAG, "Sent to dropbox:");
1761                        //Slog.i(TAG, dropBuilder.toString());
1762                        synchronized (ActivityManagerService.this) {
1763                            long now = SystemClock.uptimeMillis();
1764                            if (mLastMemUsageReportTime < now) {
1765                                mLastMemUsageReportTime = now;
1766                            }
1767                        }
1768                    }
1769                };
1770                thread.start();
1771                break;
1772            }
1773            case START_USER_SWITCH_MSG: {
1774                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1775                break;
1776            }
1777            case REPORT_USER_SWITCH_MSG: {
1778                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1779                break;
1780            }
1781            case CONTINUE_USER_SWITCH_MSG: {
1782                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1783                break;
1784            }
1785            case USER_SWITCH_TIMEOUT_MSG: {
1786                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1787                break;
1788            }
1789            case IMMERSIVE_MODE_LOCK_MSG: {
1790                final boolean nextState = (msg.arg1 != 0);
1791                if (mUpdateLock.isHeld() != nextState) {
1792                    if (DEBUG_IMMERSIVE) {
1793                        final ActivityRecord r = (ActivityRecord) msg.obj;
1794                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1795                    }
1796                    if (nextState) {
1797                        mUpdateLock.acquire();
1798                    } else {
1799                        mUpdateLock.release();
1800                    }
1801                }
1802                break;
1803            }
1804            case PERSIST_URI_GRANTS_MSG: {
1805                writeGrantedUriPermissions();
1806                break;
1807            }
1808            case REQUEST_ALL_PSS_MSG: {
1809                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1810                break;
1811            }
1812            case START_PROFILES_MSG: {
1813                synchronized (ActivityManagerService.this) {
1814                    startProfilesLocked();
1815                }
1816                break;
1817            }
1818            case UPDATE_TIME: {
1819                synchronized (ActivityManagerService.this) {
1820                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1821                        ProcessRecord r = mLruProcesses.get(i);
1822                        if (r.thread != null) {
1823                            try {
1824                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1825                            } catch (RemoteException ex) {
1826                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1827                            }
1828                        }
1829                    }
1830                }
1831                break;
1832            }
1833            case SYSTEM_USER_START_MSG: {
1834                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1835                        Integer.toString(msg.arg1), msg.arg1);
1836                mSystemServiceManager.startUser(msg.arg1);
1837                break;
1838            }
1839            case SYSTEM_USER_CURRENT_MSG: {
1840                mBatteryStatsService.noteEvent(
1841                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1842                        Integer.toString(msg.arg2), msg.arg2);
1843                mBatteryStatsService.noteEvent(
1844                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1845                        Integer.toString(msg.arg1), msg.arg1);
1846                mSystemServiceManager.switchUser(msg.arg1);
1847                mLockToAppRequest.clearPrompt();
1848                break;
1849            }
1850            case ENTER_ANIMATION_COMPLETE_MSG: {
1851                synchronized (ActivityManagerService.this) {
1852                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1853                    if (r != null && r.app != null && r.app.thread != null) {
1854                        try {
1855                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1856                        } catch (RemoteException e) {
1857                        }
1858                    }
1859                }
1860                break;
1861            }
1862            case ENABLE_SCREEN_AFTER_BOOT_MSG: {
1863                enableScreenAfterBoot();
1864                break;
1865            }
1866            }
1867        }
1868    };
1869
1870    static final int COLLECT_PSS_BG_MSG = 1;
1871
1872    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1873        @Override
1874        public void handleMessage(Message msg) {
1875            switch (msg.what) {
1876            case COLLECT_PSS_BG_MSG: {
1877                long start = SystemClock.uptimeMillis();
1878                MemInfoReader memInfo = null;
1879                synchronized (ActivityManagerService.this) {
1880                    if (mFullPssPending) {
1881                        mFullPssPending = false;
1882                        memInfo = new MemInfoReader();
1883                    }
1884                }
1885                if (memInfo != null) {
1886                    updateCpuStatsNow();
1887                    long nativeTotalPss = 0;
1888                    synchronized (mProcessCpuThread) {
1889                        final int N = mProcessCpuTracker.countStats();
1890                        for (int j=0; j<N; j++) {
1891                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1892                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1893                                // This is definitely an application process; skip it.
1894                                continue;
1895                            }
1896                            synchronized (mPidsSelfLocked) {
1897                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1898                                    // This is one of our own processes; skip it.
1899                                    continue;
1900                                }
1901                            }
1902                            nativeTotalPss += Debug.getPss(st.pid, null);
1903                        }
1904                    }
1905                    memInfo.readMemInfo();
1906                    synchronized (this) {
1907                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1908                                + (SystemClock.uptimeMillis()-start) + "ms");
1909                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1910                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1911                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1912                                        +memInfo.getSlabSizeKb(),
1913                                nativeTotalPss);
1914                    }
1915                }
1916
1917                int i=0, num=0;
1918                long[] tmp = new long[1];
1919                do {
1920                    ProcessRecord proc;
1921                    int procState;
1922                    int pid;
1923                    synchronized (ActivityManagerService.this) {
1924                        if (i >= mPendingPssProcesses.size()) {
1925                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1926                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1927                            mPendingPssProcesses.clear();
1928                            return;
1929                        }
1930                        proc = mPendingPssProcesses.get(i);
1931                        procState = proc.pssProcState;
1932                        if (proc.thread != null && procState == proc.setProcState) {
1933                            pid = proc.pid;
1934                        } else {
1935                            proc = null;
1936                            pid = 0;
1937                        }
1938                        i++;
1939                    }
1940                    if (proc != null) {
1941                        long pss = Debug.getPss(pid, tmp);
1942                        synchronized (ActivityManagerService.this) {
1943                            if (proc.thread != null && proc.setProcState == procState
1944                                    && proc.pid == pid) {
1945                                num++;
1946                                proc.lastPssTime = SystemClock.uptimeMillis();
1947                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1948                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1949                                        + ": " + pss + " lastPss=" + proc.lastPss
1950                                        + " state=" + ProcessList.makeProcStateString(procState));
1951                                if (proc.initialIdlePss == 0) {
1952                                    proc.initialIdlePss = pss;
1953                                }
1954                                proc.lastPss = pss;
1955                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1956                                    proc.lastCachedPss = pss;
1957                                }
1958                            }
1959                        }
1960                    }
1961                } while (true);
1962            }
1963            }
1964        }
1965    };
1966
1967    /**
1968     * Monitor for package changes and update our internal state.
1969     */
1970    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1971        @Override
1972        public void onPackageRemoved(String packageName, int uid) {
1973            // Remove all tasks with activities in the specified package from the list of recent tasks
1974            synchronized (ActivityManagerService.this) {
1975                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1976                    TaskRecord tr = mRecentTasks.get(i);
1977                    ComponentName cn = tr.intent.getComponent();
1978                    if (cn != null && cn.getPackageName().equals(packageName)) {
1979                        // If the package name matches, remove the task and kill the process
1980                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1981                    }
1982                }
1983            }
1984        }
1985
1986        @Override
1987        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1988            onPackageModified(packageName);
1989            return true;
1990        }
1991
1992        @Override
1993        public void onPackageModified(String packageName) {
1994            final PackageManager pm = mContext.getPackageManager();
1995            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1996                    new ArrayList<Pair<Intent, Integer>>();
1997            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1998            // Copy the list of recent tasks so that we don't hold onto the lock on
1999            // ActivityManagerService for long periods while checking if components exist.
2000            synchronized (ActivityManagerService.this) {
2001                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2002                    TaskRecord tr = mRecentTasks.get(i);
2003                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
2004                }
2005            }
2006            // Check the recent tasks and filter out all tasks with components that no longer exist.
2007            Intent tmpI = new Intent();
2008            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
2009                Pair<Intent, Integer> p = recentTaskIntents.get(i);
2010                ComponentName cn = p.first.getComponent();
2011                if (cn != null && cn.getPackageName().equals(packageName)) {
2012                    try {
2013                        // Add the task to the list to remove if the component no longer exists
2014                        tmpI.setComponent(cn);
2015                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
2016                            tasksToRemove.add(p.second);
2017                        }
2018                    } catch (Exception e) {}
2019                }
2020            }
2021            // Prune all the tasks with removed components from the list of recent tasks
2022            synchronized (ActivityManagerService.this) {
2023                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
2024                    // Remove the task but don't kill the process (since other components in that
2025                    // package may still be running and in the background)
2026                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
2027                }
2028            }
2029        }
2030
2031        @Override
2032        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2033            // Force stop the specified packages
2034            if (packages != null) {
2035                for (String pkg : packages) {
2036                    synchronized (ActivityManagerService.this) {
2037                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
2038                                "finished booting")) {
2039                            return true;
2040                        }
2041                    }
2042                }
2043            }
2044            return false;
2045        }
2046    };
2047
2048    public void setSystemProcess() {
2049        try {
2050            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2051            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2052            ServiceManager.addService("meminfo", new MemBinder(this));
2053            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2054            ServiceManager.addService("dbinfo", new DbBinder(this));
2055            if (MONITOR_CPU_USAGE) {
2056                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2057            }
2058            ServiceManager.addService("permission", new PermissionController(this));
2059
2060            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2061                    "android", STOCK_PM_FLAGS);
2062            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2063
2064            synchronized (this) {
2065                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2066                app.persistent = true;
2067                app.pid = MY_PID;
2068                app.maxAdj = ProcessList.SYSTEM_ADJ;
2069                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2070                mProcessNames.put(app.processName, app.uid, app);
2071                synchronized (mPidsSelfLocked) {
2072                    mPidsSelfLocked.put(app.pid, app);
2073                }
2074                updateLruProcessLocked(app, false, null);
2075                updateOomAdjLocked();
2076            }
2077        } catch (PackageManager.NameNotFoundException e) {
2078            throw new RuntimeException(
2079                    "Unable to find android system package", e);
2080        }
2081    }
2082
2083    public void setWindowManager(WindowManagerService wm) {
2084        mWindowManager = wm;
2085        mStackSupervisor.setWindowManager(wm);
2086    }
2087
2088    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2089        mUsageStatsService = usageStatsManager;
2090    }
2091
2092    public void startObservingNativeCrashes() {
2093        final NativeCrashListener ncl = new NativeCrashListener(this);
2094        ncl.start();
2095    }
2096
2097    public IAppOpsService getAppOpsService() {
2098        return mAppOpsService;
2099    }
2100
2101    static class MemBinder extends Binder {
2102        ActivityManagerService mActivityManagerService;
2103        MemBinder(ActivityManagerService activityManagerService) {
2104            mActivityManagerService = activityManagerService;
2105        }
2106
2107        @Override
2108        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2109            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2110                    != PackageManager.PERMISSION_GRANTED) {
2111                pw.println("Permission Denial: can't dump meminfo from from pid="
2112                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2113                        + " without permission " + android.Manifest.permission.DUMP);
2114                return;
2115            }
2116
2117            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2118        }
2119    }
2120
2121    static class GraphicsBinder extends Binder {
2122        ActivityManagerService mActivityManagerService;
2123        GraphicsBinder(ActivityManagerService activityManagerService) {
2124            mActivityManagerService = activityManagerService;
2125        }
2126
2127        @Override
2128        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2129            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2130                    != PackageManager.PERMISSION_GRANTED) {
2131                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2132                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2133                        + " without permission " + android.Manifest.permission.DUMP);
2134                return;
2135            }
2136
2137            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2138        }
2139    }
2140
2141    static class DbBinder extends Binder {
2142        ActivityManagerService mActivityManagerService;
2143        DbBinder(ActivityManagerService activityManagerService) {
2144            mActivityManagerService = activityManagerService;
2145        }
2146
2147        @Override
2148        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2149            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2150                    != PackageManager.PERMISSION_GRANTED) {
2151                pw.println("Permission Denial: can't dump dbinfo from from pid="
2152                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2153                        + " without permission " + android.Manifest.permission.DUMP);
2154                return;
2155            }
2156
2157            mActivityManagerService.dumpDbInfo(fd, pw, args);
2158        }
2159    }
2160
2161    static class CpuBinder extends Binder {
2162        ActivityManagerService mActivityManagerService;
2163        CpuBinder(ActivityManagerService activityManagerService) {
2164            mActivityManagerService = activityManagerService;
2165        }
2166
2167        @Override
2168        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2169            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2170                    != PackageManager.PERMISSION_GRANTED) {
2171                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2172                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2173                        + " without permission " + android.Manifest.permission.DUMP);
2174                return;
2175            }
2176
2177            synchronized (mActivityManagerService.mProcessCpuThread) {
2178                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2179                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2180                        SystemClock.uptimeMillis()));
2181            }
2182        }
2183    }
2184
2185    public static final class Lifecycle extends SystemService {
2186        private final ActivityManagerService mService;
2187
2188        public Lifecycle(Context context) {
2189            super(context);
2190            mService = new ActivityManagerService(context);
2191        }
2192
2193        @Override
2194        public void onStart() {
2195            mService.start();
2196        }
2197
2198        public ActivityManagerService getService() {
2199            return mService;
2200        }
2201    }
2202
2203    // Note: This method is invoked on the main thread but may need to attach various
2204    // handlers to other threads.  So take care to be explicit about the looper.
2205    public ActivityManagerService(Context systemContext) {
2206        mContext = systemContext;
2207        mFactoryTest = FactoryTest.getMode();
2208        mSystemThread = ActivityThread.currentActivityThread();
2209
2210        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2211
2212        mHandlerThread = new ServiceThread(TAG,
2213                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2214        mHandlerThread.start();
2215        mHandler = new MainHandler(mHandlerThread.getLooper());
2216
2217        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2218                "foreground", BROADCAST_FG_TIMEOUT, false);
2219        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2220                "background", BROADCAST_BG_TIMEOUT, true);
2221        mBroadcastQueues[0] = mFgBroadcastQueue;
2222        mBroadcastQueues[1] = mBgBroadcastQueue;
2223
2224        mServices = new ActiveServices(this);
2225        mProviderMap = new ProviderMap(this);
2226
2227        // TODO: Move creation of battery stats service outside of activity manager service.
2228        File dataDir = Environment.getDataDirectory();
2229        File systemDir = new File(dataDir, "system");
2230        systemDir.mkdirs();
2231        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2232        mBatteryStatsService.getActiveStatistics().readLocked();
2233        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2234        mOnBattery = DEBUG_POWER ? true
2235                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2236        mBatteryStatsService.getActiveStatistics().setCallback(this);
2237
2238        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2239
2240        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2241
2242        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2243
2244        // User 0 is the first and only user that runs at boot.
2245        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2246        mUserLru.add(Integer.valueOf(0));
2247        updateStartedUserArrayLocked();
2248
2249        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2250            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2251
2252        mConfiguration.setToDefaults();
2253        mConfiguration.setLocale(Locale.getDefault());
2254
2255        mConfigurationSeq = mConfiguration.seq = 1;
2256        mProcessCpuTracker.init();
2257
2258        final Resources res = mContext.getResources();
2259        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
2260        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
2261        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
2262
2263        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2264        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2265        mStackSupervisor = new ActivityStackSupervisor(this);
2266        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2267
2268        mProcessCpuThread = new Thread("CpuTracker") {
2269            @Override
2270            public void run() {
2271                while (true) {
2272                    try {
2273                        try {
2274                            synchronized(this) {
2275                                final long now = SystemClock.uptimeMillis();
2276                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2277                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2278                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2279                                //        + ", write delay=" + nextWriteDelay);
2280                                if (nextWriteDelay < nextCpuDelay) {
2281                                    nextCpuDelay = nextWriteDelay;
2282                                }
2283                                if (nextCpuDelay > 0) {
2284                                    mProcessCpuMutexFree.set(true);
2285                                    this.wait(nextCpuDelay);
2286                                }
2287                            }
2288                        } catch (InterruptedException e) {
2289                        }
2290                        updateCpuStatsNow();
2291                    } catch (Exception e) {
2292                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2293                    }
2294                }
2295            }
2296        };
2297
2298        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2299
2300        Watchdog.getInstance().addMonitor(this);
2301        Watchdog.getInstance().addThread(mHandler);
2302    }
2303
2304    public void setSystemServiceManager(SystemServiceManager mgr) {
2305        mSystemServiceManager = mgr;
2306    }
2307
2308    private void start() {
2309        Process.removeAllProcessGroups();
2310        mProcessCpuThread.start();
2311
2312        mBatteryStatsService.publish(mContext);
2313        mAppOpsService.publish(mContext);
2314        Slog.d("AppOps", "AppOpsService published");
2315        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2316    }
2317
2318    public void initPowerManagement() {
2319        mStackSupervisor.initPowerManagement();
2320        mBatteryStatsService.initPowerManagement();
2321    }
2322
2323    @Override
2324    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2325            throws RemoteException {
2326        if (code == SYSPROPS_TRANSACTION) {
2327            // We need to tell all apps about the system property change.
2328            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2329            synchronized(this) {
2330                final int NP = mProcessNames.getMap().size();
2331                for (int ip=0; ip<NP; ip++) {
2332                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2333                    final int NA = apps.size();
2334                    for (int ia=0; ia<NA; ia++) {
2335                        ProcessRecord app = apps.valueAt(ia);
2336                        if (app.thread != null) {
2337                            procs.add(app.thread.asBinder());
2338                        }
2339                    }
2340                }
2341            }
2342
2343            int N = procs.size();
2344            for (int i=0; i<N; i++) {
2345                Parcel data2 = Parcel.obtain();
2346                try {
2347                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2348                } catch (RemoteException e) {
2349                }
2350                data2.recycle();
2351            }
2352        }
2353        try {
2354            return super.onTransact(code, data, reply, flags);
2355        } catch (RuntimeException e) {
2356            // The activity manager only throws security exceptions, so let's
2357            // log all others.
2358            if (!(e instanceof SecurityException)) {
2359                Slog.wtf(TAG, "Activity Manager Crash", e);
2360            }
2361            throw e;
2362        }
2363    }
2364
2365    void updateCpuStats() {
2366        final long now = SystemClock.uptimeMillis();
2367        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2368            return;
2369        }
2370        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2371            synchronized (mProcessCpuThread) {
2372                mProcessCpuThread.notify();
2373            }
2374        }
2375    }
2376
2377    void updateCpuStatsNow() {
2378        synchronized (mProcessCpuThread) {
2379            mProcessCpuMutexFree.set(false);
2380            final long now = SystemClock.uptimeMillis();
2381            boolean haveNewCpuStats = false;
2382
2383            if (MONITOR_CPU_USAGE &&
2384                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2385                mLastCpuTime.set(now);
2386                haveNewCpuStats = true;
2387                mProcessCpuTracker.update();
2388                //Slog.i(TAG, mProcessCpu.printCurrentState());
2389                //Slog.i(TAG, "Total CPU usage: "
2390                //        + mProcessCpu.getTotalCpuPercent() + "%");
2391
2392                // Slog the cpu usage if the property is set.
2393                if ("true".equals(SystemProperties.get("events.cpu"))) {
2394                    int user = mProcessCpuTracker.getLastUserTime();
2395                    int system = mProcessCpuTracker.getLastSystemTime();
2396                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2397                    int irq = mProcessCpuTracker.getLastIrqTime();
2398                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2399                    int idle = mProcessCpuTracker.getLastIdleTime();
2400
2401                    int total = user + system + iowait + irq + softIrq + idle;
2402                    if (total == 0) total = 1;
2403
2404                    EventLog.writeEvent(EventLogTags.CPU,
2405                            ((user+system+iowait+irq+softIrq) * 100) / total,
2406                            (user * 100) / total,
2407                            (system * 100) / total,
2408                            (iowait * 100) / total,
2409                            (irq * 100) / total,
2410                            (softIrq * 100) / total);
2411                }
2412            }
2413
2414            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2415            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2416            synchronized(bstats) {
2417                synchronized(mPidsSelfLocked) {
2418                    if (haveNewCpuStats) {
2419                        if (mOnBattery) {
2420                            int perc = bstats.startAddingCpuLocked();
2421                            int totalUTime = 0;
2422                            int totalSTime = 0;
2423                            final int N = mProcessCpuTracker.countStats();
2424                            for (int i=0; i<N; i++) {
2425                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2426                                if (!st.working) {
2427                                    continue;
2428                                }
2429                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2430                                int otherUTime = (st.rel_utime*perc)/100;
2431                                int otherSTime = (st.rel_stime*perc)/100;
2432                                totalUTime += otherUTime;
2433                                totalSTime += otherSTime;
2434                                if (pr != null) {
2435                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2436                                    if (ps == null || !ps.isActive()) {
2437                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2438                                                pr.info.uid, pr.processName);
2439                                    }
2440                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2441                                            st.rel_stime-otherSTime);
2442                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2443                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2444                                } else {
2445                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2446                                    if (ps == null || !ps.isActive()) {
2447                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2448                                                bstats.mapUid(st.uid), st.name);
2449                                    }
2450                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2451                                            st.rel_stime-otherSTime);
2452                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2453                                }
2454                            }
2455                            bstats.finishAddingCpuLocked(perc, totalUTime,
2456                                    totalSTime, cpuSpeedTimes);
2457                        }
2458                    }
2459                }
2460
2461                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2462                    mLastWriteTime = now;
2463                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2464                }
2465            }
2466        }
2467    }
2468
2469    @Override
2470    public void batteryNeedsCpuUpdate() {
2471        updateCpuStatsNow();
2472    }
2473
2474    @Override
2475    public void batteryPowerChanged(boolean onBattery) {
2476        // When plugging in, update the CPU stats first before changing
2477        // the plug state.
2478        updateCpuStatsNow();
2479        synchronized (this) {
2480            synchronized(mPidsSelfLocked) {
2481                mOnBattery = DEBUG_POWER ? true : onBattery;
2482            }
2483        }
2484    }
2485
2486    /**
2487     * Initialize the application bind args. These are passed to each
2488     * process when the bindApplication() IPC is sent to the process. They're
2489     * lazily setup to make sure the services are running when they're asked for.
2490     */
2491    private HashMap<String, IBinder> getCommonServicesLocked() {
2492        if (mAppBindArgs == null) {
2493            mAppBindArgs = new HashMap<String, IBinder>();
2494
2495            // Setup the application init args
2496            mAppBindArgs.put("package", ServiceManager.getService("package"));
2497            mAppBindArgs.put("window", ServiceManager.getService("window"));
2498            mAppBindArgs.put(Context.ALARM_SERVICE,
2499                    ServiceManager.getService(Context.ALARM_SERVICE));
2500        }
2501        return mAppBindArgs;
2502    }
2503
2504    final void setFocusedActivityLocked(ActivityRecord r) {
2505        if (mFocusedActivity != r) {
2506            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2507            mFocusedActivity = r;
2508            if (r.task != null && r.task.voiceInteractor != null) {
2509                startRunningVoiceLocked();
2510            } else {
2511                finishRunningVoiceLocked();
2512            }
2513            mStackSupervisor.setFocusedStack(r);
2514            if (r != null) {
2515                mWindowManager.setFocusedApp(r.appToken, true);
2516            }
2517            applyUpdateLockStateLocked(r);
2518        }
2519    }
2520
2521    final void clearFocusedActivity(ActivityRecord r) {
2522        if (mFocusedActivity == r) {
2523            mFocusedActivity = null;
2524        }
2525    }
2526
2527    @Override
2528    public void setFocusedStack(int stackId) {
2529        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2530        synchronized (ActivityManagerService.this) {
2531            ActivityStack stack = mStackSupervisor.getStack(stackId);
2532            if (stack != null) {
2533                ActivityRecord r = stack.topRunningActivityLocked(null);
2534                if (r != null) {
2535                    setFocusedActivityLocked(r);
2536                }
2537            }
2538        }
2539    }
2540
2541    @Override
2542    public void notifyActivityDrawn(IBinder token) {
2543        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2544        synchronized (this) {
2545            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2546            if (r != null) {
2547                r.task.stack.notifyActivityDrawnLocked(r);
2548            }
2549        }
2550    }
2551
2552    final void applyUpdateLockStateLocked(ActivityRecord r) {
2553        // Modifications to the UpdateLock state are done on our handler, outside
2554        // the activity manager's locks.  The new state is determined based on the
2555        // state *now* of the relevant activity record.  The object is passed to
2556        // the handler solely for logging detail, not to be consulted/modified.
2557        final boolean nextState = r != null && r.immersive;
2558        mHandler.sendMessage(
2559                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2560    }
2561
2562    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2563        Message msg = Message.obtain();
2564        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2565        msg.obj = r.task.askedCompatMode ? null : r;
2566        mHandler.sendMessage(msg);
2567    }
2568
2569    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2570            String what, Object obj, ProcessRecord srcApp) {
2571        app.lastActivityTime = now;
2572
2573        if (app.activities.size() > 0) {
2574            // Don't want to touch dependent processes that are hosting activities.
2575            return index;
2576        }
2577
2578        int lrui = mLruProcesses.lastIndexOf(app);
2579        if (lrui < 0) {
2580            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2581                    + what + " " + obj + " from " + srcApp);
2582            return index;
2583        }
2584
2585        if (lrui >= index) {
2586            // Don't want to cause this to move dependent processes *back* in the
2587            // list as if they were less frequently used.
2588            return index;
2589        }
2590
2591        if (lrui >= mLruProcessActivityStart) {
2592            // Don't want to touch dependent processes that are hosting activities.
2593            return index;
2594        }
2595
2596        mLruProcesses.remove(lrui);
2597        if (index > 0) {
2598            index--;
2599        }
2600        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2601                + " in LRU list: " + app);
2602        mLruProcesses.add(index, app);
2603        return index;
2604    }
2605
2606    final void removeLruProcessLocked(ProcessRecord app) {
2607        int lrui = mLruProcesses.lastIndexOf(app);
2608        if (lrui >= 0) {
2609            if (lrui <= mLruProcessActivityStart) {
2610                mLruProcessActivityStart--;
2611            }
2612            if (lrui <= mLruProcessServiceStart) {
2613                mLruProcessServiceStart--;
2614            }
2615            mLruProcesses.remove(lrui);
2616        }
2617    }
2618
2619    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2620            ProcessRecord client) {
2621        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2622                || app.treatLikeActivity;
2623        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2624        if (!activityChange && hasActivity) {
2625            // The process has activities, so we are only allowing activity-based adjustments
2626            // to move it.  It should be kept in the front of the list with other
2627            // processes that have activities, and we don't want those to change their
2628            // order except due to activity operations.
2629            return;
2630        }
2631
2632        mLruSeq++;
2633        final long now = SystemClock.uptimeMillis();
2634        app.lastActivityTime = now;
2635
2636        // First a quick reject: if the app is already at the position we will
2637        // put it, then there is nothing to do.
2638        if (hasActivity) {
2639            final int N = mLruProcesses.size();
2640            if (N > 0 && mLruProcesses.get(N-1) == app) {
2641                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2642                return;
2643            }
2644        } else {
2645            if (mLruProcessServiceStart > 0
2646                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2647                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2648                return;
2649            }
2650        }
2651
2652        int lrui = mLruProcesses.lastIndexOf(app);
2653
2654        if (app.persistent && lrui >= 0) {
2655            // We don't care about the position of persistent processes, as long as
2656            // they are in the list.
2657            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2658            return;
2659        }
2660
2661        /* In progress: compute new position first, so we can avoid doing work
2662           if the process is not actually going to move.  Not yet working.
2663        int addIndex;
2664        int nextIndex;
2665        boolean inActivity = false, inService = false;
2666        if (hasActivity) {
2667            // Process has activities, put it at the very tipsy-top.
2668            addIndex = mLruProcesses.size();
2669            nextIndex = mLruProcessServiceStart;
2670            inActivity = true;
2671        } else if (hasService) {
2672            // Process has services, put it at the top of the service list.
2673            addIndex = mLruProcessActivityStart;
2674            nextIndex = mLruProcessServiceStart;
2675            inActivity = true;
2676            inService = true;
2677        } else  {
2678            // Process not otherwise of interest, it goes to the top of the non-service area.
2679            addIndex = mLruProcessServiceStart;
2680            if (client != null) {
2681                int clientIndex = mLruProcesses.lastIndexOf(client);
2682                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2683                        + app);
2684                if (clientIndex >= 0 && addIndex > clientIndex) {
2685                    addIndex = clientIndex;
2686                }
2687            }
2688            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2689        }
2690
2691        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2692                + mLruProcessActivityStart + "): " + app);
2693        */
2694
2695        if (lrui >= 0) {
2696            if (lrui < mLruProcessActivityStart) {
2697                mLruProcessActivityStart--;
2698            }
2699            if (lrui < mLruProcessServiceStart) {
2700                mLruProcessServiceStart--;
2701            }
2702            /*
2703            if (addIndex > lrui) {
2704                addIndex--;
2705            }
2706            if (nextIndex > lrui) {
2707                nextIndex--;
2708            }
2709            */
2710            mLruProcesses.remove(lrui);
2711        }
2712
2713        /*
2714        mLruProcesses.add(addIndex, app);
2715        if (inActivity) {
2716            mLruProcessActivityStart++;
2717        }
2718        if (inService) {
2719            mLruProcessActivityStart++;
2720        }
2721        */
2722
2723        int nextIndex;
2724        if (hasActivity) {
2725            final int N = mLruProcesses.size();
2726            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2727                // Process doesn't have activities, but has clients with
2728                // activities...  move it up, but one below the top (the top
2729                // should always have a real activity).
2730                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2731                mLruProcesses.add(N-1, app);
2732                // To keep it from spamming the LRU list (by making a bunch of clients),
2733                // we will push down any other entries owned by the app.
2734                final int uid = app.info.uid;
2735                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2736                    ProcessRecord subProc = mLruProcesses.get(i);
2737                    if (subProc.info.uid == uid) {
2738                        // We want to push this one down the list.  If the process after
2739                        // it is for the same uid, however, don't do so, because we don't
2740                        // want them internally to be re-ordered.
2741                        if (mLruProcesses.get(i-1).info.uid != uid) {
2742                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2743                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2744                            ProcessRecord tmp = mLruProcesses.get(i);
2745                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2746                            mLruProcesses.set(i-1, tmp);
2747                            i--;
2748                        }
2749                    } else {
2750                        // A gap, we can stop here.
2751                        break;
2752                    }
2753                }
2754            } else {
2755                // Process has activities, put it at the very tipsy-top.
2756                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2757                mLruProcesses.add(app);
2758            }
2759            nextIndex = mLruProcessServiceStart;
2760        } else if (hasService) {
2761            // Process has services, put it at the top of the service list.
2762            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2763            mLruProcesses.add(mLruProcessActivityStart, app);
2764            nextIndex = mLruProcessServiceStart;
2765            mLruProcessActivityStart++;
2766        } else  {
2767            // Process not otherwise of interest, it goes to the top of the non-service area.
2768            int index = mLruProcessServiceStart;
2769            if (client != null) {
2770                // If there is a client, don't allow the process to be moved up higher
2771                // in the list than that client.
2772                int clientIndex = mLruProcesses.lastIndexOf(client);
2773                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2774                        + " when updating " + app);
2775                if (clientIndex <= lrui) {
2776                    // Don't allow the client index restriction to push it down farther in the
2777                    // list than it already is.
2778                    clientIndex = lrui;
2779                }
2780                if (clientIndex >= 0 && index > clientIndex) {
2781                    index = clientIndex;
2782                }
2783            }
2784            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2785            mLruProcesses.add(index, app);
2786            nextIndex = index-1;
2787            mLruProcessActivityStart++;
2788            mLruProcessServiceStart++;
2789        }
2790
2791        // If the app is currently using a content provider or service,
2792        // bump those processes as well.
2793        for (int j=app.connections.size()-1; j>=0; j--) {
2794            ConnectionRecord cr = app.connections.valueAt(j);
2795            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2796                    && cr.binding.service.app != null
2797                    && cr.binding.service.app.lruSeq != mLruSeq
2798                    && !cr.binding.service.app.persistent) {
2799                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2800                        "service connection", cr, app);
2801            }
2802        }
2803        for (int j=app.conProviders.size()-1; j>=0; j--) {
2804            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2805            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2806                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2807                        "provider reference", cpr, app);
2808            }
2809        }
2810    }
2811
2812    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2813        if (uid == Process.SYSTEM_UID) {
2814            // The system gets to run in any process.  If there are multiple
2815            // processes with the same uid, just pick the first (this
2816            // should never happen).
2817            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2818            if (procs == null) return null;
2819            final int N = procs.size();
2820            for (int i = 0; i < N; i++) {
2821                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2822            }
2823        }
2824        ProcessRecord proc = mProcessNames.get(processName, uid);
2825        if (false && proc != null && !keepIfLarge
2826                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2827                && proc.lastCachedPss >= 4000) {
2828            // Turn this condition on to cause killing to happen regularly, for testing.
2829            if (proc.baseProcessTracker != null) {
2830                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2831            }
2832            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2833        } else if (proc != null && !keepIfLarge
2834                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2835                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2836            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2837            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2838                if (proc.baseProcessTracker != null) {
2839                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2840                }
2841                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2842            }
2843        }
2844        return proc;
2845    }
2846
2847    void ensurePackageDexOpt(String packageName) {
2848        IPackageManager pm = AppGlobals.getPackageManager();
2849        try {
2850            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2851                mDidDexOpt = true;
2852            }
2853        } catch (RemoteException e) {
2854        }
2855    }
2856
2857    boolean isNextTransitionForward() {
2858        int transit = mWindowManager.getPendingAppTransition();
2859        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2860                || transit == AppTransition.TRANSIT_TASK_OPEN
2861                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2862    }
2863
2864    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2865            String processName, String abiOverride, int uid, Runnable crashHandler) {
2866        synchronized(this) {
2867            ApplicationInfo info = new ApplicationInfo();
2868            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2869            // For isolated processes, the former contains the parent's uid and the latter the
2870            // actual uid of the isolated process.
2871            // In the special case introduced by this method (which is, starting an isolated
2872            // process directly from the SystemServer without an actual parent app process) the
2873            // closest thing to a parent's uid is SYSTEM_UID.
2874            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2875            // the |isolated| logic in the ProcessRecord constructor.
2876            info.uid = Process.SYSTEM_UID;
2877            info.processName = processName;
2878            info.className = entryPoint;
2879            info.packageName = "android";
2880            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2881                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2882                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2883                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2884                    crashHandler);
2885            return proc != null ? proc.pid : 0;
2886        }
2887    }
2888
2889    final ProcessRecord startProcessLocked(String processName,
2890            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2891            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2892            boolean isolated, boolean keepIfLarge) {
2893        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2894                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2895                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2896                null /* crashHandler */);
2897    }
2898
2899    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2900            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2901            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2902            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2903        ProcessRecord app;
2904        if (!isolated) {
2905            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2906        } else {
2907            // If this is an isolated process, it can't re-use an existing process.
2908            app = null;
2909        }
2910        // We don't have to do anything more if:
2911        // (1) There is an existing application record; and
2912        // (2) The caller doesn't think it is dead, OR there is no thread
2913        //     object attached to it so we know it couldn't have crashed; and
2914        // (3) There is a pid assigned to it, so it is either starting or
2915        //     already running.
2916        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2917                + " app=" + app + " knownToBeDead=" + knownToBeDead
2918                + " thread=" + (app != null ? app.thread : null)
2919                + " pid=" + (app != null ? app.pid : -1));
2920        if (app != null && app.pid > 0) {
2921            if (!knownToBeDead || app.thread == null) {
2922                // We already have the app running, or are waiting for it to
2923                // come up (we have a pid but not yet its thread), so keep it.
2924                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2925                // If this is a new package in the process, add the package to the list
2926                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2927                return app;
2928            }
2929
2930            // An application record is attached to a previous process,
2931            // clean it up now.
2932            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2933            Process.killProcessGroup(app.info.uid, app.pid);
2934            handleAppDiedLocked(app, true, true);
2935        }
2936
2937        String hostingNameStr = hostingName != null
2938                ? hostingName.flattenToShortString() : null;
2939
2940        if (!isolated) {
2941            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2942                // If we are in the background, then check to see if this process
2943                // is bad.  If so, we will just silently fail.
2944                if (mBadProcesses.get(info.processName, info.uid) != null) {
2945                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2946                            + "/" + info.processName);
2947                    return null;
2948                }
2949            } else {
2950                // When the user is explicitly starting a process, then clear its
2951                // crash count so that we won't make it bad until they see at
2952                // least one crash dialog again, and make the process good again
2953                // if it had been bad.
2954                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2955                        + "/" + info.processName);
2956                mProcessCrashTimes.remove(info.processName, info.uid);
2957                if (mBadProcesses.get(info.processName, info.uid) != null) {
2958                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2959                            UserHandle.getUserId(info.uid), info.uid,
2960                            info.processName);
2961                    mBadProcesses.remove(info.processName, info.uid);
2962                    if (app != null) {
2963                        app.bad = false;
2964                    }
2965                }
2966            }
2967        }
2968
2969        if (app == null) {
2970            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2971            app.crashHandler = crashHandler;
2972            if (app == null) {
2973                Slog.w(TAG, "Failed making new process record for "
2974                        + processName + "/" + info.uid + " isolated=" + isolated);
2975                return null;
2976            }
2977            mProcessNames.put(processName, app.uid, app);
2978            if (isolated) {
2979                mIsolatedProcesses.put(app.uid, app);
2980            }
2981        } else {
2982            // If this is a new package in the process, add the package to the list
2983            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2984        }
2985
2986        // If the system is not ready yet, then hold off on starting this
2987        // process until it is.
2988        if (!mProcessesReady
2989                && !isAllowedWhileBooting(info)
2990                && !allowWhileBooting) {
2991            if (!mProcessesOnHold.contains(app)) {
2992                mProcessesOnHold.add(app);
2993            }
2994            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2995            return app;
2996        }
2997
2998        startProcessLocked(
2999                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3000        return (app.pid != 0) ? app : null;
3001    }
3002
3003    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3004        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3005    }
3006
3007    private final void startProcessLocked(ProcessRecord app,
3008            String hostingType, String hostingNameStr) {
3009        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3010                null /* entryPoint */, null /* entryPointArgs */);
3011    }
3012
3013    private final void startProcessLocked(ProcessRecord app, String hostingType,
3014            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3015        if (app.pid > 0 && app.pid != MY_PID) {
3016            synchronized (mPidsSelfLocked) {
3017                mPidsSelfLocked.remove(app.pid);
3018                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3019            }
3020            app.setPid(0);
3021        }
3022
3023        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3024                "startProcessLocked removing on hold: " + app);
3025        mProcessesOnHold.remove(app);
3026
3027        updateCpuStats();
3028
3029        try {
3030            int uid = app.uid;
3031
3032            int[] gids = null;
3033            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3034            if (!app.isolated) {
3035                int[] permGids = null;
3036                try {
3037                    final PackageManager pm = mContext.getPackageManager();
3038                    permGids = pm.getPackageGids(app.info.packageName);
3039
3040                    if (Environment.isExternalStorageEmulated()) {
3041                        if (pm.checkPermission(
3042                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3043                                app.info.packageName) == PERMISSION_GRANTED) {
3044                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3045                        } else {
3046                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3047                        }
3048                    }
3049                } catch (PackageManager.NameNotFoundException e) {
3050                    Slog.w(TAG, "Unable to retrieve gids", e);
3051                }
3052
3053                /*
3054                 * Add shared application and profile GIDs so applications can share some
3055                 * resources like shared libraries and access user-wide resources
3056                 */
3057                if (permGids == null) {
3058                    gids = new int[2];
3059                } else {
3060                    gids = new int[permGids.length + 2];
3061                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3062                }
3063                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3064                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3065            }
3066            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3067                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3068                        && mTopComponent != null
3069                        && app.processName.equals(mTopComponent.getPackageName())) {
3070                    uid = 0;
3071                }
3072                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3073                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3074                    uid = 0;
3075                }
3076            }
3077            int debugFlags = 0;
3078            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3079                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3080                // Also turn on CheckJNI for debuggable apps. It's quite
3081                // awkward to turn on otherwise.
3082                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3083            }
3084            // Run the app in safe mode if its manifest requests so or the
3085            // system is booted in safe mode.
3086            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3087                mSafeMode == true) {
3088                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3089            }
3090            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3091                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3092            }
3093            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3094                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3095            }
3096            if ("1".equals(SystemProperties.get("debug.assert"))) {
3097                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3098            }
3099
3100            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3101            if (requiredAbi == null) {
3102                requiredAbi = Build.SUPPORTED_ABIS[0];
3103            }
3104
3105            // Start the process.  It will either succeed and return a result containing
3106            // the PID of the new process, or else throw a RuntimeException.
3107            boolean isActivityProcess = (entryPoint == null);
3108            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3109            Process.ProcessStartResult startResult = Process.start(entryPoint,
3110                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3111                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, entryPointArgs);
3112
3113            if (app.isolated) {
3114                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3115            }
3116            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3117
3118            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3119                    UserHandle.getUserId(uid), startResult.pid, uid,
3120                    app.processName, hostingType,
3121                    hostingNameStr != null ? hostingNameStr : "");
3122
3123            if (app.persistent) {
3124                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3125            }
3126
3127            StringBuilder buf = mStringBuilder;
3128            buf.setLength(0);
3129            buf.append("Start proc ");
3130            buf.append(app.processName);
3131            if (!isActivityProcess) {
3132                buf.append(" [");
3133                buf.append(entryPoint);
3134                buf.append("]");
3135            }
3136            buf.append(" for ");
3137            buf.append(hostingType);
3138            if (hostingNameStr != null) {
3139                buf.append(" ");
3140                buf.append(hostingNameStr);
3141            }
3142            buf.append(": pid=");
3143            buf.append(startResult.pid);
3144            buf.append(" uid=");
3145            buf.append(uid);
3146            buf.append(" gids={");
3147            if (gids != null) {
3148                for (int gi=0; gi<gids.length; gi++) {
3149                    if (gi != 0) buf.append(", ");
3150                    buf.append(gids[gi]);
3151
3152                }
3153            }
3154            buf.append("}");
3155            if (requiredAbi != null) {
3156                buf.append(" abi=");
3157                buf.append(requiredAbi);
3158            }
3159            Slog.i(TAG, buf.toString());
3160            app.setPid(startResult.pid);
3161            app.usingWrapper = startResult.usingWrapper;
3162            app.removed = false;
3163            app.killedByAm = false;
3164            synchronized (mPidsSelfLocked) {
3165                this.mPidsSelfLocked.put(startResult.pid, app);
3166                if (isActivityProcess) {
3167                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3168                    msg.obj = app;
3169                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3170                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3171                }
3172            }
3173        } catch (RuntimeException e) {
3174            // XXX do better error recovery.
3175            app.setPid(0);
3176            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3177            if (app.isolated) {
3178                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3179            }
3180            Slog.e(TAG, "Failure starting process " + app.processName, e);
3181        }
3182    }
3183
3184    void updateUsageStats(ActivityRecord component, boolean resumed) {
3185        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3186        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3187        if (resumed) {
3188            if (mUsageStatsService != null) {
3189                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3190                        System.currentTimeMillis(),
3191                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3192            }
3193            synchronized (stats) {
3194                stats.noteActivityResumedLocked(component.app.uid);
3195            }
3196        } else {
3197            if (mUsageStatsService != null) {
3198                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3199                        System.currentTimeMillis(),
3200                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3201            }
3202            synchronized (stats) {
3203                stats.noteActivityPausedLocked(component.app.uid);
3204            }
3205        }
3206    }
3207
3208    Intent getHomeIntent() {
3209        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3210        intent.setComponent(mTopComponent);
3211        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3212            intent.addCategory(Intent.CATEGORY_HOME);
3213        }
3214        return intent;
3215    }
3216
3217    boolean startHomeActivityLocked(int userId) {
3218        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3219                && mTopAction == null) {
3220            // We are running in factory test mode, but unable to find
3221            // the factory test app, so just sit around displaying the
3222            // error message and don't try to start anything.
3223            return false;
3224        }
3225        Intent intent = getHomeIntent();
3226        ActivityInfo aInfo =
3227            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3228        if (aInfo != null) {
3229            intent.setComponent(new ComponentName(
3230                    aInfo.applicationInfo.packageName, aInfo.name));
3231            // Don't do this if the home app is currently being
3232            // instrumented.
3233            aInfo = new ActivityInfo(aInfo);
3234            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3235            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3236                    aInfo.applicationInfo.uid, true);
3237            if (app == null || app.instrumentationClass == null) {
3238                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3239                mStackSupervisor.startHomeActivity(intent, aInfo);
3240            }
3241        }
3242
3243        return true;
3244    }
3245
3246    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3247        ActivityInfo ai = null;
3248        ComponentName comp = intent.getComponent();
3249        try {
3250            if (comp != null) {
3251                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3252            } else {
3253                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3254                        intent,
3255                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3256                            flags, userId);
3257
3258                if (info != null) {
3259                    ai = info.activityInfo;
3260                }
3261            }
3262        } catch (RemoteException e) {
3263            // ignore
3264        }
3265
3266        return ai;
3267    }
3268
3269    /**
3270     * Starts the "new version setup screen" if appropriate.
3271     */
3272    void startSetupActivityLocked() {
3273        // Only do this once per boot.
3274        if (mCheckedForSetup) {
3275            return;
3276        }
3277
3278        // We will show this screen if the current one is a different
3279        // version than the last one shown, and we are not running in
3280        // low-level factory test mode.
3281        final ContentResolver resolver = mContext.getContentResolver();
3282        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3283                Settings.Global.getInt(resolver,
3284                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3285            mCheckedForSetup = true;
3286
3287            // See if we should be showing the platform update setup UI.
3288            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3289            List<ResolveInfo> ris = mContext.getPackageManager()
3290                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3291
3292            // We don't allow third party apps to replace this.
3293            ResolveInfo ri = null;
3294            for (int i=0; ris != null && i<ris.size(); i++) {
3295                if ((ris.get(i).activityInfo.applicationInfo.flags
3296                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3297                    ri = ris.get(i);
3298                    break;
3299                }
3300            }
3301
3302            if (ri != null) {
3303                String vers = ri.activityInfo.metaData != null
3304                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3305                        : null;
3306                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3307                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3308                            Intent.METADATA_SETUP_VERSION);
3309                }
3310                String lastVers = Settings.Secure.getString(
3311                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3312                if (vers != null && !vers.equals(lastVers)) {
3313                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3314                    intent.setComponent(new ComponentName(
3315                            ri.activityInfo.packageName, ri.activityInfo.name));
3316                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3317                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null,
3318                            null);
3319                }
3320            }
3321        }
3322    }
3323
3324    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3325        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3326    }
3327
3328    void enforceNotIsolatedCaller(String caller) {
3329        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3330            throw new SecurityException("Isolated process not allowed to call " + caller);
3331        }
3332    }
3333
3334    @Override
3335    public int getFrontActivityScreenCompatMode() {
3336        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3337        synchronized (this) {
3338            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3339        }
3340    }
3341
3342    @Override
3343    public void setFrontActivityScreenCompatMode(int mode) {
3344        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3345                "setFrontActivityScreenCompatMode");
3346        synchronized (this) {
3347            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3348        }
3349    }
3350
3351    @Override
3352    public int getPackageScreenCompatMode(String packageName) {
3353        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3354        synchronized (this) {
3355            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3356        }
3357    }
3358
3359    @Override
3360    public void setPackageScreenCompatMode(String packageName, int mode) {
3361        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3362                "setPackageScreenCompatMode");
3363        synchronized (this) {
3364            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3365        }
3366    }
3367
3368    @Override
3369    public boolean getPackageAskScreenCompat(String packageName) {
3370        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3371        synchronized (this) {
3372            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3373        }
3374    }
3375
3376    @Override
3377    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3378        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3379                "setPackageAskScreenCompat");
3380        synchronized (this) {
3381            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3382        }
3383    }
3384
3385    private void dispatchProcessesChanged() {
3386        int N;
3387        synchronized (this) {
3388            N = mPendingProcessChanges.size();
3389            if (mActiveProcessChanges.length < N) {
3390                mActiveProcessChanges = new ProcessChangeItem[N];
3391            }
3392            mPendingProcessChanges.toArray(mActiveProcessChanges);
3393            mAvailProcessChanges.addAll(mPendingProcessChanges);
3394            mPendingProcessChanges.clear();
3395            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3396        }
3397
3398        int i = mProcessObservers.beginBroadcast();
3399        while (i > 0) {
3400            i--;
3401            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3402            if (observer != null) {
3403                try {
3404                    for (int j=0; j<N; j++) {
3405                        ProcessChangeItem item = mActiveProcessChanges[j];
3406                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3407                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3408                                    + item.pid + " uid=" + item.uid + ": "
3409                                    + item.foregroundActivities);
3410                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3411                                    item.foregroundActivities);
3412                        }
3413                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3414                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3415                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3416                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3417                        }
3418                    }
3419                } catch (RemoteException e) {
3420                }
3421            }
3422        }
3423        mProcessObservers.finishBroadcast();
3424    }
3425
3426    private void dispatchProcessDied(int pid, int uid) {
3427        int i = mProcessObservers.beginBroadcast();
3428        while (i > 0) {
3429            i--;
3430            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3431            if (observer != null) {
3432                try {
3433                    observer.onProcessDied(pid, uid);
3434                } catch (RemoteException e) {
3435                }
3436            }
3437        }
3438        mProcessObservers.finishBroadcast();
3439    }
3440
3441    @Override
3442    public final int startActivity(IApplicationThread caller, String callingPackage,
3443            Intent intent, String resolvedType, IBinder resultTo,
3444            String resultWho, int requestCode, int startFlags,
3445            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3446        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3447                resultWho, requestCode,
3448                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3449    }
3450
3451    @Override
3452    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3453            Intent intent, String resolvedType, IBinder resultTo,
3454            String resultWho, int requestCode, int startFlags,
3455            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3456        enforceNotIsolatedCaller("startActivity");
3457        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3458                false, ALLOW_FULL_ONLY, "startActivity", null);
3459        // TODO: Switch to user app stacks here.
3460        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3461                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3462                null, null, options, userId, null, null);
3463    }
3464
3465    @Override
3466    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3467            Intent intent, String resolvedType, IBinder resultTo,
3468            String resultWho, int requestCode, int startFlags,
3469            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3470
3471        // This is very dangerous -- it allows you to perform a start activity (including
3472        // permission grants) as any app that may launch one of your own activities.  So
3473        // we will only allow this to be done from activities that are part of the core framework,
3474        // and then only when they are running as the system.
3475        final ActivityRecord sourceRecord;
3476        final int targetUid;
3477        final String targetPackage;
3478        synchronized (this) {
3479            if (resultTo == null) {
3480                throw new SecurityException("Must be called from an activity");
3481            }
3482            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3483            if (sourceRecord == null) {
3484                throw new SecurityException("Called with bad activity token: " + resultTo);
3485            }
3486            if (!sourceRecord.info.packageName.equals("android")) {
3487                throw new SecurityException(
3488                        "Must be called from an activity that is declared in the android package");
3489            }
3490            if (sourceRecord.app == null) {
3491                throw new SecurityException("Called without a process attached to activity");
3492            }
3493            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3494                // This is still okay, as long as this activity is running under the
3495                // uid of the original calling activity.
3496                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3497                    throw new SecurityException(
3498                            "Calling activity in uid " + sourceRecord.app.uid
3499                                    + " must be system uid or original calling uid "
3500                                    + sourceRecord.launchedFromUid);
3501                }
3502            }
3503            targetUid = sourceRecord.launchedFromUid;
3504            targetPackage = sourceRecord.launchedFromPackage;
3505        }
3506
3507        // TODO: Switch to user app stacks here.
3508        try {
3509            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3510                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3511                    null, null, null, null, options, UserHandle.getUserId(sourceRecord.app.uid),
3512                    null, null);
3513            return ret;
3514        } catch (SecurityException e) {
3515            // XXX need to figure out how to propagate to original app.
3516            // A SecurityException here is generally actually a fault of the original
3517            // calling activity (such as a fairly granting permissions), so propagate it
3518            // back to them.
3519            /*
3520            StringBuilder msg = new StringBuilder();
3521            msg.append("While launching");
3522            msg.append(intent.toString());
3523            msg.append(": ");
3524            msg.append(e.getMessage());
3525            */
3526            throw e;
3527        }
3528    }
3529
3530    @Override
3531    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3532            Intent intent, String resolvedType, IBinder resultTo,
3533            String resultWho, int requestCode, int startFlags, String profileFile,
3534            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3535        enforceNotIsolatedCaller("startActivityAndWait");
3536        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3537                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3538        WaitResult res = new WaitResult();
3539        // TODO: Switch to user app stacks here.
3540        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3541                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3542                res, null, options, userId, null, null);
3543        return res;
3544    }
3545
3546    @Override
3547    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3548            Intent intent, String resolvedType, IBinder resultTo,
3549            String resultWho, int requestCode, int startFlags, Configuration config,
3550            Bundle options, int userId) {
3551        enforceNotIsolatedCaller("startActivityWithConfig");
3552        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3553                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3554        // TODO: Switch to user app stacks here.
3555        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3556                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3557                null, null, null, config, options, userId, null, null);
3558        return ret;
3559    }
3560
3561    @Override
3562    public int startActivityIntentSender(IApplicationThread caller,
3563            IntentSender intent, Intent fillInIntent, String resolvedType,
3564            IBinder resultTo, String resultWho, int requestCode,
3565            int flagsMask, int flagsValues, Bundle options) {
3566        enforceNotIsolatedCaller("startActivityIntentSender");
3567        // Refuse possible leaked file descriptors
3568        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3569            throw new IllegalArgumentException("File descriptors passed in Intent");
3570        }
3571
3572        IIntentSender sender = intent.getTarget();
3573        if (!(sender instanceof PendingIntentRecord)) {
3574            throw new IllegalArgumentException("Bad PendingIntent object");
3575        }
3576
3577        PendingIntentRecord pir = (PendingIntentRecord)sender;
3578
3579        synchronized (this) {
3580            // If this is coming from the currently resumed activity, it is
3581            // effectively saying that app switches are allowed at this point.
3582            final ActivityStack stack = getFocusedStack();
3583            if (stack.mResumedActivity != null &&
3584                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3585                mAppSwitchesAllowedTime = 0;
3586            }
3587        }
3588        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3589                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3590        return ret;
3591    }
3592
3593    @Override
3594    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3595            Intent intent, String resolvedType, IVoiceInteractionSession session,
3596            IVoiceInteractor interactor, int startFlags, String profileFile,
3597            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3598        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3599                != PackageManager.PERMISSION_GRANTED) {
3600            String msg = "Permission Denial: startVoiceActivity() from pid="
3601                    + Binder.getCallingPid()
3602                    + ", uid=" + Binder.getCallingUid()
3603                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3604            Slog.w(TAG, msg);
3605            throw new SecurityException(msg);
3606        }
3607        if (session == null || interactor == null) {
3608            throw new NullPointerException("null session or interactor");
3609        }
3610        userId = handleIncomingUser(callingPid, callingUid, userId,
3611                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3612        // TODO: Switch to user app stacks here.
3613        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3614                resolvedType, session, interactor, null, null, 0, startFlags,
3615                profileFile, profileFd, null, null, options, userId, null, null);
3616    }
3617
3618    @Override
3619    public boolean startNextMatchingActivity(IBinder callingActivity,
3620            Intent intent, Bundle options) {
3621        // Refuse possible leaked file descriptors
3622        if (intent != null && intent.hasFileDescriptors() == true) {
3623            throw new IllegalArgumentException("File descriptors passed in Intent");
3624        }
3625
3626        synchronized (this) {
3627            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3628            if (r == null) {
3629                ActivityOptions.abort(options);
3630                return false;
3631            }
3632            if (r.app == null || r.app.thread == null) {
3633                // The caller is not running...  d'oh!
3634                ActivityOptions.abort(options);
3635                return false;
3636            }
3637            intent = new Intent(intent);
3638            // The caller is not allowed to change the data.
3639            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3640            // And we are resetting to find the next component...
3641            intent.setComponent(null);
3642
3643            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3644
3645            ActivityInfo aInfo = null;
3646            try {
3647                List<ResolveInfo> resolves =
3648                    AppGlobals.getPackageManager().queryIntentActivities(
3649                            intent, r.resolvedType,
3650                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3651                            UserHandle.getCallingUserId());
3652
3653                // Look for the original activity in the list...
3654                final int N = resolves != null ? resolves.size() : 0;
3655                for (int i=0; i<N; i++) {
3656                    ResolveInfo rInfo = resolves.get(i);
3657                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3658                            && rInfo.activityInfo.name.equals(r.info.name)) {
3659                        // We found the current one...  the next matching is
3660                        // after it.
3661                        i++;
3662                        if (i<N) {
3663                            aInfo = resolves.get(i).activityInfo;
3664                        }
3665                        if (debug) {
3666                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3667                                    + "/" + r.info.name);
3668                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3669                                    + "/" + aInfo.name);
3670                        }
3671                        break;
3672                    }
3673                }
3674            } catch (RemoteException e) {
3675            }
3676
3677            if (aInfo == null) {
3678                // Nobody who is next!
3679                ActivityOptions.abort(options);
3680                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3681                return false;
3682            }
3683
3684            intent.setComponent(new ComponentName(
3685                    aInfo.applicationInfo.packageName, aInfo.name));
3686            intent.setFlags(intent.getFlags()&~(
3687                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3688                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3689                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3690                    Intent.FLAG_ACTIVITY_NEW_TASK));
3691
3692            // Okay now we need to start the new activity, replacing the
3693            // currently running activity.  This is a little tricky because
3694            // we want to start the new one as if the current one is finished,
3695            // but not finish the current one first so that there is no flicker.
3696            // And thus...
3697            final boolean wasFinishing = r.finishing;
3698            r.finishing = true;
3699
3700            // Propagate reply information over to the new activity.
3701            final ActivityRecord resultTo = r.resultTo;
3702            final String resultWho = r.resultWho;
3703            final int requestCode = r.requestCode;
3704            r.resultTo = null;
3705            if (resultTo != null) {
3706                resultTo.removeResultsLocked(r, resultWho, requestCode);
3707            }
3708
3709            final long origId = Binder.clearCallingIdentity();
3710            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3711                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3712                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3713                    options, false, null, null, null);
3714            Binder.restoreCallingIdentity(origId);
3715
3716            r.finishing = wasFinishing;
3717            if (res != ActivityManager.START_SUCCESS) {
3718                return false;
3719            }
3720            return true;
3721        }
3722    }
3723
3724    @Override
3725    public final int startActivityFromRecents(int taskId, Bundle options) {
3726        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3727            String msg = "Permission Denial: startActivityFromRecents called without " +
3728                    START_TASKS_FROM_RECENTS;
3729            Slog.w(TAG, msg);
3730            throw new SecurityException(msg);
3731        }
3732        return startActivityFromRecentsInner(taskId, options);
3733    }
3734
3735    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3736        final TaskRecord task;
3737        final int callingUid;
3738        final String callingPackage;
3739        final Intent intent;
3740        final int userId;
3741        synchronized (this) {
3742            task = recentTaskForIdLocked(taskId);
3743            if (task == null) {
3744                throw new IllegalArgumentException("Task " + taskId + " not found.");
3745            }
3746            callingUid = task.mCallingUid;
3747            callingPackage = task.mCallingPackage;
3748            intent = task.intent;
3749            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3750            userId = task.userId;
3751        }
3752        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3753                options, userId, null, task);
3754    }
3755
3756    final int startActivityInPackage(int uid, String callingPackage,
3757            Intent intent, String resolvedType, IBinder resultTo,
3758            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3759            IActivityContainer container, TaskRecord inTask) {
3760
3761        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3762                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3763
3764        // TODO: Switch to user app stacks here.
3765        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3766                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3767                null, null, null, null, options, userId, container, inTask);
3768        return ret;
3769    }
3770
3771    @Override
3772    public final int startActivities(IApplicationThread caller, String callingPackage,
3773            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3774            int userId) {
3775        enforceNotIsolatedCaller("startActivities");
3776        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3777                false, ALLOW_FULL_ONLY, "startActivity", null);
3778        // TODO: Switch to user app stacks here.
3779        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3780                resolvedTypes, resultTo, options, userId);
3781        return ret;
3782    }
3783
3784    final int startActivitiesInPackage(int uid, String callingPackage,
3785            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3786            Bundle options, int userId) {
3787
3788        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3789                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3790        // TODO: Switch to user app stacks here.
3791        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3792                resultTo, options, userId);
3793        return ret;
3794    }
3795
3796    //explicitly remove thd old information in mRecentTasks when removing existing user.
3797    private void removeRecentTasksForUserLocked(int userId) {
3798        if(userId <= 0) {
3799            Slog.i(TAG, "Can't remove recent task on user " + userId);
3800            return;
3801        }
3802
3803        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3804            TaskRecord tr = mRecentTasks.get(i);
3805            if (tr.userId == userId) {
3806                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3807                        + " when finishing user" + userId);
3808                mRecentTasks.remove(i);
3809                tr.removedFromRecents(mTaskPersister);
3810            }
3811        }
3812
3813        // Remove tasks from persistent storage.
3814        mTaskPersister.wakeup(null, true);
3815    }
3816
3817    /**
3818     * Update the recent tasks lists: make sure tasks should still be here (their
3819     * applications / activities still exist), update their availability, fixup ordering
3820     * of affiliations.
3821     */
3822    void cleanupRecentTasksLocked(int userId) {
3823        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3824        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3825        final IPackageManager pm = AppGlobals.getPackageManager();
3826        final ActivityInfo dummyAct = new ActivityInfo();
3827        final ApplicationInfo dummyApp = new ApplicationInfo();
3828
3829        int N = mRecentTasks.size();
3830
3831        int[] users = userId == UserHandle.USER_ALL
3832                ? getUsersLocked() : new int[] { userId };
3833        for (int user : users) {
3834            for (int i = 0; i < N; i++) {
3835                TaskRecord task = mRecentTasks.get(i);
3836                if (task.userId != user) {
3837                    // Only look at tasks for the user ID of interest.
3838                    continue;
3839                }
3840                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3841                    // This situation is broken, and we should just get rid of it now.
3842                    mRecentTasks.remove(i);
3843                    task.removedFromRecents(mTaskPersister);
3844                    i--;
3845                    N--;
3846                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3847                    continue;
3848                }
3849                // Check whether this activity is currently available.
3850                if (task.realActivity != null) {
3851                    ActivityInfo ai = availActCache.get(task.realActivity);
3852                    if (ai == null) {
3853                        try {
3854                            ai = pm.getActivityInfo(task.realActivity,
3855                                    PackageManager.GET_UNINSTALLED_PACKAGES
3856                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3857                        } catch (RemoteException e) {
3858                            // Will never happen.
3859                            continue;
3860                        }
3861                        if (ai == null) {
3862                            ai = dummyAct;
3863                        }
3864                        availActCache.put(task.realActivity, ai);
3865                    }
3866                    if (ai == dummyAct) {
3867                        // This could be either because the activity no longer exists, or the
3868                        // app is temporarily gone.  For the former we want to remove the recents
3869                        // entry; for the latter we want to mark it as unavailable.
3870                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3871                        if (app == null) {
3872                            try {
3873                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3874                                        PackageManager.GET_UNINSTALLED_PACKAGES
3875                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3876                            } catch (RemoteException e) {
3877                                // Will never happen.
3878                                continue;
3879                            }
3880                            if (app == null) {
3881                                app = dummyApp;
3882                            }
3883                            availAppCache.put(task.realActivity.getPackageName(), app);
3884                        }
3885                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3886                            // Doesn't exist any more!  Good-bye.
3887                            mRecentTasks.remove(i);
3888                            task.removedFromRecents(mTaskPersister);
3889                            i--;
3890                            N--;
3891                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3892                            continue;
3893                        } else {
3894                            // Otherwise just not available for now.
3895                            if (task.isAvailable) {
3896                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3897                                        + task);
3898                            }
3899                            task.isAvailable = false;
3900                        }
3901                    } else {
3902                        if (!ai.enabled || !ai.applicationInfo.enabled
3903                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3904                            if (task.isAvailable) {
3905                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3906                                        + task + " (enabled=" + ai.enabled + "/"
3907                                        + ai.applicationInfo.enabled +  " flags="
3908                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3909                            }
3910                            task.isAvailable = false;
3911                        } else {
3912                            if (!task.isAvailable) {
3913                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3914                                        + task);
3915                            }
3916                            task.isAvailable = true;
3917                        }
3918                    }
3919                }
3920            }
3921        }
3922
3923        // Verify the affiliate chain for each task.
3924        for (int i = 0; i < N; ) {
3925            TaskRecord task = mRecentTasks.remove(i);
3926            if (mTmpRecents.contains(task)) {
3927                continue;
3928            }
3929            int affiliatedTaskId = task.mAffiliatedTaskId;
3930            while (true) {
3931                TaskRecord next = task.mNextAffiliate;
3932                if (next == null) {
3933                    break;
3934                }
3935                if (next.mAffiliatedTaskId != affiliatedTaskId) {
3936                    Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
3937                            next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
3938                    task.setNextAffiliate(null);
3939                    if (next.mPrevAffiliate == task) {
3940                        next.setPrevAffiliate(null);
3941                    }
3942                    break;
3943                }
3944                if (next.mPrevAffiliate != task) {
3945                    Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
3946                            next.mPrevAffiliate + " task=" + task);
3947                    next.setPrevAffiliate(null);
3948                    task.setNextAffiliate(null);
3949                    break;
3950                }
3951                if (!mRecentTasks.contains(next)) {
3952                    Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
3953                    task.setNextAffiliate(null);
3954                    // We know that next.mPrevAffiliate is always task, from above, so clear
3955                    // its previous affiliate.
3956                    next.setPrevAffiliate(null);
3957                    break;
3958                }
3959                task = next;
3960            }
3961            // task is now the end of the list
3962            do {
3963                mRecentTasks.remove(task);
3964                mRecentTasks.add(i++, task);
3965                mTmpRecents.add(task);
3966                task.inRecents = true;
3967            } while ((task = task.mPrevAffiliate) != null);
3968        }
3969        mTmpRecents.clear();
3970        // mRecentTasks is now in sorted, affiliated order.
3971    }
3972
3973    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
3974        int N = mRecentTasks.size();
3975        TaskRecord top = task;
3976        int topIndex = taskIndex;
3977        while (top.mNextAffiliate != null && topIndex > 0) {
3978            top = top.mNextAffiliate;
3979            topIndex--;
3980        }
3981        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
3982                + topIndex + " from intial " + taskIndex);
3983        // Find the end of the chain, doing a sanity check along the way.
3984        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
3985        int endIndex = topIndex;
3986        TaskRecord prev = top;
3987        while (endIndex < N) {
3988            TaskRecord cur = mRecentTasks.get(endIndex);
3989            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
3990                    + endIndex + " " + cur);
3991            if (cur == top) {
3992                // Verify start of the chain.
3993                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
3994                    Slog.wtf(TAG, "Bad chain @" + endIndex
3995                            + ": first task has next affiliate: " + prev);
3996                    sane = false;
3997                    break;
3998                }
3999            } else {
4000                // Verify middle of the chain's next points back to the one before.
4001                if (cur.mNextAffiliate != prev
4002                        || cur.mNextAffiliateTaskId != prev.taskId) {
4003                    Slog.wtf(TAG, "Bad chain @" + endIndex
4004                            + ": middle task " + cur + " @" + endIndex
4005                            + " has bad next affiliate "
4006                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
4007                            + ", expected " + prev);
4008                    sane = false;
4009                    break;
4010                }
4011            }
4012            if (cur.mPrevAffiliateTaskId == -1) {
4013                // Chain ends here.
4014                if (cur.mPrevAffiliate != null) {
4015                    Slog.wtf(TAG, "Bad chain @" + endIndex
4016                            + ": last task " + cur + " has previous affiliate "
4017                            + cur.mPrevAffiliate);
4018                    sane = false;
4019                }
4020                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
4021                break;
4022            } else {
4023                // Verify middle of the chain's prev points to a valid item.
4024                if (cur.mPrevAffiliate == null) {
4025                    Slog.wtf(TAG, "Bad chain @" + endIndex
4026                            + ": task " + cur + " has previous affiliate "
4027                            + cur.mPrevAffiliate + " but should be id "
4028                            + cur.mPrevAffiliate);
4029                    sane = false;
4030                    break;
4031                }
4032            }
4033            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
4034                Slog.wtf(TAG, "Bad chain @" + endIndex
4035                        + ": task " + cur + " has affiliated id "
4036                        + cur.mAffiliatedTaskId + " but should be "
4037                        + task.mAffiliatedTaskId);
4038                sane = false;
4039                break;
4040            }
4041            prev = cur;
4042            endIndex++;
4043            if (endIndex >= N) {
4044                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4045                        + ": last task " + prev);
4046                sane = false;
4047                break;
4048            }
4049        }
4050        if (sane) {
4051            if (endIndex < taskIndex) {
4052                Slog.wtf(TAG, "Bad chain @" + endIndex
4053                        + ": did not extend to task " + task + " @" + taskIndex);
4054                sane = false;
4055            }
4056        }
4057        if (sane) {
4058            // All looks good, we can just move all of the affiliated tasks
4059            // to the top.
4060            for (int i=topIndex; i<=endIndex; i++) {
4061                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4062                        + " from " + i + " to " + (i-topIndex));
4063                TaskRecord cur = mRecentTasks.remove(i);
4064                mRecentTasks.add(i-topIndex, cur);
4065            }
4066            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4067                    + " to " + endIndex);
4068            return true;
4069        }
4070
4071        // Whoops, couldn't do it.
4072        return false;
4073    }
4074
4075    final void addRecentTaskLocked(TaskRecord task) {
4076        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4077                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4078
4079        int N = mRecentTasks.size();
4080        // Quick case: check if the top-most recent task is the same.
4081        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4082            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4083            return;
4084        }
4085        // Another quick case: check if this is part of a set of affiliated
4086        // tasks that are at the top.
4087        if (isAffiliated && N > 0 && task.inRecents
4088                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4089            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4090                    + " at top when adding " + task);
4091            return;
4092        }
4093        // Another quick case: never add voice sessions.
4094        if (task.voiceSession != null) {
4095            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4096            return;
4097        }
4098
4099        boolean needAffiliationFix = false;
4100
4101        // Slightly less quick case: the task is already in recents, so all we need
4102        // to do is move it.
4103        if (task.inRecents) {
4104            int taskIndex = mRecentTasks.indexOf(task);
4105            if (taskIndex >= 0) {
4106                if (!isAffiliated) {
4107                    // Simple case: this is not an affiliated task, so we just move it to the front.
4108                    mRecentTasks.remove(taskIndex);
4109                    mRecentTasks.add(0, task);
4110                    notifyTaskPersisterLocked(task, false);
4111                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4112                            + " from " + taskIndex);
4113                    return;
4114                } else {
4115                    // More complicated: need to keep all affiliated tasks together.
4116                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4117                        // All went well.
4118                        return;
4119                    }
4120
4121                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4122                    // everything and then go through our general path of adding a new task.
4123                    needAffiliationFix = true;
4124                }
4125            } else {
4126                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4127                needAffiliationFix = true;
4128            }
4129        }
4130
4131        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4132        trimRecentsForTask(task, true);
4133
4134        N = mRecentTasks.size();
4135        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4136            final TaskRecord tr = mRecentTasks.remove(N - 1);
4137            tr.removedFromRecents(mTaskPersister);
4138            N--;
4139        }
4140        task.inRecents = true;
4141        if (!isAffiliated || needAffiliationFix) {
4142            // If this is a simple non-affiliated task, or we had some failure trying to
4143            // handle it as part of an affilated task, then just place it at the top.
4144            mRecentTasks.add(0, task);
4145        } else if (isAffiliated) {
4146            // If this is a new affiliated task, then move all of the affiliated tasks
4147            // to the front and insert this new one.
4148            TaskRecord other = task.mNextAffiliate;
4149            if (other == null) {
4150                other = task.mPrevAffiliate;
4151            }
4152            if (other != null) {
4153                int otherIndex = mRecentTasks.indexOf(other);
4154                if (otherIndex >= 0) {
4155                    // Insert new task at appropriate location.
4156                    int taskIndex;
4157                    if (other == task.mNextAffiliate) {
4158                        // We found the index of our next affiliation, which is who is
4159                        // before us in the list, so add after that point.
4160                        taskIndex = otherIndex+1;
4161                    } else {
4162                        // We found the index of our previous affiliation, which is who is
4163                        // after us in the list, so add at their position.
4164                        taskIndex = otherIndex;
4165                    }
4166                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4167                            + taskIndex + ": " + task);
4168                    mRecentTasks.add(taskIndex, task);
4169
4170                    // Now move everything to the front.
4171                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4172                        // All went well.
4173                        return;
4174                    }
4175
4176                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4177                    // everything and then go through our general path of adding a new task.
4178                    needAffiliationFix = true;
4179                } else {
4180                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4181                            + other);
4182                    needAffiliationFix = true;
4183                }
4184            } else {
4185                if (DEBUG_RECENTS) Slog.d(TAG,
4186                        "addRecent: adding affiliated task without next/prev:" + task);
4187                needAffiliationFix = true;
4188            }
4189        }
4190        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4191
4192        if (needAffiliationFix) {
4193            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4194            cleanupRecentTasksLocked(task.userId);
4195        }
4196    }
4197
4198    /**
4199     * If needed, remove oldest existing entries in recents that are for the same kind
4200     * of task as the given one.
4201     */
4202    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4203        int N = mRecentTasks.size();
4204        final Intent intent = task.intent;
4205        final boolean document = intent != null && intent.isDocument();
4206
4207        int maxRecents = task.maxRecents - 1;
4208        for (int i=0; i<N; i++) {
4209            final TaskRecord tr = mRecentTasks.get(i);
4210            if (task != tr) {
4211                if (task.userId != tr.userId) {
4212                    continue;
4213                }
4214                if (i > MAX_RECENT_BITMAPS) {
4215                    tr.freeLastThumbnail();
4216                }
4217                final Intent trIntent = tr.intent;
4218                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4219                    (intent == null || !intent.filterEquals(trIntent))) {
4220                    continue;
4221                }
4222                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4223                if (document && trIsDocument) {
4224                    // These are the same document activity (not necessarily the same doc).
4225                    if (maxRecents > 0) {
4226                        --maxRecents;
4227                        continue;
4228                    }
4229                    // Hit the maximum number of documents for this task. Fall through
4230                    // and remove this document from recents.
4231                } else if (document || trIsDocument) {
4232                    // Only one of these is a document. Not the droid we're looking for.
4233                    continue;
4234                }
4235            }
4236
4237            if (!doTrim) {
4238                // If the caller is not actually asking for a trim, just tell them we reached
4239                // a point where the trim would happen.
4240                return i;
4241            }
4242
4243            // Either task and tr are the same or, their affinities match or their intents match
4244            // and neither of them is a document, or they are documents using the same activity
4245            // and their maxRecents has been reached.
4246            tr.disposeThumbnail();
4247            mRecentTasks.remove(i);
4248            if (task != tr) {
4249                tr.removedFromRecents(mTaskPersister);
4250            }
4251            i--;
4252            N--;
4253            if (task.intent == null) {
4254                // If the new recent task we are adding is not fully
4255                // specified, then replace it with the existing recent task.
4256                task = tr;
4257            }
4258            notifyTaskPersisterLocked(tr, false);
4259        }
4260
4261        return -1;
4262    }
4263
4264    @Override
4265    public void reportActivityFullyDrawn(IBinder token) {
4266        synchronized (this) {
4267            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4268            if (r == null) {
4269                return;
4270            }
4271            r.reportFullyDrawnLocked();
4272        }
4273    }
4274
4275    @Override
4276    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4277        synchronized (this) {
4278            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4279            if (r == null) {
4280                return;
4281            }
4282            final long origId = Binder.clearCallingIdentity();
4283            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4284            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4285                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4286            if (config != null) {
4287                r.frozenBeforeDestroy = true;
4288                if (!updateConfigurationLocked(config, r, false, false)) {
4289                    mStackSupervisor.resumeTopActivitiesLocked();
4290                }
4291            }
4292            Binder.restoreCallingIdentity(origId);
4293        }
4294    }
4295
4296    @Override
4297    public int getRequestedOrientation(IBinder token) {
4298        synchronized (this) {
4299            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4300            if (r == null) {
4301                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4302            }
4303            return mWindowManager.getAppOrientation(r.appToken);
4304        }
4305    }
4306
4307    /**
4308     * This is the internal entry point for handling Activity.finish().
4309     *
4310     * @param token The Binder token referencing the Activity we want to finish.
4311     * @param resultCode Result code, if any, from this Activity.
4312     * @param resultData Result data (Intent), if any, from this Activity.
4313     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4314     *            the root Activity in the task.
4315     *
4316     * @return Returns true if the activity successfully finished, or false if it is still running.
4317     */
4318    @Override
4319    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4320            boolean finishTask) {
4321        // Refuse possible leaked file descriptors
4322        if (resultData != null && resultData.hasFileDescriptors() == true) {
4323            throw new IllegalArgumentException("File descriptors passed in Intent");
4324        }
4325
4326        synchronized(this) {
4327            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4328            if (r == null) {
4329                return true;
4330            }
4331            // Keep track of the root activity of the task before we finish it
4332            TaskRecord tr = r.task;
4333            ActivityRecord rootR = tr.getRootActivity();
4334            // Do not allow task to finish in Lock Task mode.
4335            if (tr == mStackSupervisor.mLockTaskModeTask) {
4336                if (rootR == r) {
4337                    mStackSupervisor.showLockTaskToast();
4338                    return false;
4339                }
4340            }
4341            if (mController != null) {
4342                // Find the first activity that is not finishing.
4343                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4344                if (next != null) {
4345                    // ask watcher if this is allowed
4346                    boolean resumeOK = true;
4347                    try {
4348                        resumeOK = mController.activityResuming(next.packageName);
4349                    } catch (RemoteException e) {
4350                        mController = null;
4351                        Watchdog.getInstance().setActivityController(null);
4352                    }
4353
4354                    if (!resumeOK) {
4355                        return false;
4356                    }
4357                }
4358            }
4359            final long origId = Binder.clearCallingIdentity();
4360            try {
4361                boolean res;
4362                if (finishTask && r == rootR) {
4363                    // If requested, remove the task that is associated to this activity only if it
4364                    // was the root activity in the task.  The result code and data is ignored because
4365                    // we don't support returning them across task boundaries.
4366                    res = removeTaskByIdLocked(tr.taskId, 0);
4367                } else {
4368                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4369                            resultData, "app-request", true);
4370                }
4371                return res;
4372            } finally {
4373                Binder.restoreCallingIdentity(origId);
4374            }
4375        }
4376    }
4377
4378    @Override
4379    public final void finishHeavyWeightApp() {
4380        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4381                != PackageManager.PERMISSION_GRANTED) {
4382            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4383                    + Binder.getCallingPid()
4384                    + ", uid=" + Binder.getCallingUid()
4385                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4386            Slog.w(TAG, msg);
4387            throw new SecurityException(msg);
4388        }
4389
4390        synchronized(this) {
4391            if (mHeavyWeightProcess == null) {
4392                return;
4393            }
4394
4395            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4396                    mHeavyWeightProcess.activities);
4397            for (int i=0; i<activities.size(); i++) {
4398                ActivityRecord r = activities.get(i);
4399                if (!r.finishing) {
4400                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4401                            null, "finish-heavy", true);
4402                }
4403            }
4404
4405            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4406                    mHeavyWeightProcess.userId, 0));
4407            mHeavyWeightProcess = null;
4408        }
4409    }
4410
4411    @Override
4412    public void crashApplication(int uid, int initialPid, String packageName,
4413            String message) {
4414        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4415                != PackageManager.PERMISSION_GRANTED) {
4416            String msg = "Permission Denial: crashApplication() from pid="
4417                    + Binder.getCallingPid()
4418                    + ", uid=" + Binder.getCallingUid()
4419                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4420            Slog.w(TAG, msg);
4421            throw new SecurityException(msg);
4422        }
4423
4424        synchronized(this) {
4425            ProcessRecord proc = null;
4426
4427            // Figure out which process to kill.  We don't trust that initialPid
4428            // still has any relation to current pids, so must scan through the
4429            // list.
4430            synchronized (mPidsSelfLocked) {
4431                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4432                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4433                    if (p.uid != uid) {
4434                        continue;
4435                    }
4436                    if (p.pid == initialPid) {
4437                        proc = p;
4438                        break;
4439                    }
4440                    if (p.pkgList.containsKey(packageName)) {
4441                        proc = p;
4442                    }
4443                }
4444            }
4445
4446            if (proc == null) {
4447                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4448                        + " initialPid=" + initialPid
4449                        + " packageName=" + packageName);
4450                return;
4451            }
4452
4453            if (proc.thread != null) {
4454                if (proc.pid == Process.myPid()) {
4455                    Log.w(TAG, "crashApplication: trying to crash self!");
4456                    return;
4457                }
4458                long ident = Binder.clearCallingIdentity();
4459                try {
4460                    proc.thread.scheduleCrash(message);
4461                } catch (RemoteException e) {
4462                }
4463                Binder.restoreCallingIdentity(ident);
4464            }
4465        }
4466    }
4467
4468    @Override
4469    public final void finishSubActivity(IBinder token, String resultWho,
4470            int requestCode) {
4471        synchronized(this) {
4472            final long origId = Binder.clearCallingIdentity();
4473            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4474            if (r != null) {
4475                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4476            }
4477            Binder.restoreCallingIdentity(origId);
4478        }
4479    }
4480
4481    @Override
4482    public boolean finishActivityAffinity(IBinder token) {
4483        synchronized(this) {
4484            final long origId = Binder.clearCallingIdentity();
4485            try {
4486                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4487
4488                ActivityRecord rootR = r.task.getRootActivity();
4489                // Do not allow task to finish in Lock Task mode.
4490                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4491                    if (rootR == r) {
4492                        mStackSupervisor.showLockTaskToast();
4493                        return false;
4494                    }
4495                }
4496                boolean res = false;
4497                if (r != null) {
4498                    res = r.task.stack.finishActivityAffinityLocked(r);
4499                }
4500                return res;
4501            } finally {
4502                Binder.restoreCallingIdentity(origId);
4503            }
4504        }
4505    }
4506
4507    @Override
4508    public void finishVoiceTask(IVoiceInteractionSession session) {
4509        synchronized(this) {
4510            final long origId = Binder.clearCallingIdentity();
4511            try {
4512                mStackSupervisor.finishVoiceTask(session);
4513            } finally {
4514                Binder.restoreCallingIdentity(origId);
4515            }
4516        }
4517
4518    }
4519
4520    @Override
4521    public boolean releaseActivityInstance(IBinder token) {
4522        synchronized(this) {
4523            final long origId = Binder.clearCallingIdentity();
4524            try {
4525                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4526                if (r.task == null || r.task.stack == null) {
4527                    return false;
4528                }
4529                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4530            } finally {
4531                Binder.restoreCallingIdentity(origId);
4532            }
4533        }
4534    }
4535
4536    @Override
4537    public void releaseSomeActivities(IApplicationThread appInt) {
4538        synchronized(this) {
4539            final long origId = Binder.clearCallingIdentity();
4540            try {
4541                ProcessRecord app = getRecordForAppLocked(appInt);
4542                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4543            } finally {
4544                Binder.restoreCallingIdentity(origId);
4545            }
4546        }
4547    }
4548
4549    @Override
4550    public boolean willActivityBeVisible(IBinder token) {
4551        synchronized(this) {
4552            ActivityStack stack = ActivityRecord.getStackLocked(token);
4553            if (stack != null) {
4554                return stack.willActivityBeVisibleLocked(token);
4555            }
4556            return false;
4557        }
4558    }
4559
4560    @Override
4561    public void overridePendingTransition(IBinder token, String packageName,
4562            int enterAnim, int exitAnim) {
4563        synchronized(this) {
4564            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4565            if (self == null) {
4566                return;
4567            }
4568
4569            final long origId = Binder.clearCallingIdentity();
4570
4571            if (self.state == ActivityState.RESUMED
4572                    || self.state == ActivityState.PAUSING) {
4573                mWindowManager.overridePendingAppTransition(packageName,
4574                        enterAnim, exitAnim, null);
4575            }
4576
4577            Binder.restoreCallingIdentity(origId);
4578        }
4579    }
4580
4581    /**
4582     * Main function for removing an existing process from the activity manager
4583     * as a result of that process going away.  Clears out all connections
4584     * to the process.
4585     */
4586    private final void handleAppDiedLocked(ProcessRecord app,
4587            boolean restarting, boolean allowRestart) {
4588        int pid = app.pid;
4589        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4590        if (!restarting) {
4591            removeLruProcessLocked(app);
4592            if (pid > 0) {
4593                ProcessList.remove(pid);
4594            }
4595        }
4596
4597        if (mProfileProc == app) {
4598            clearProfilerLocked();
4599        }
4600
4601        // Remove this application's activities from active lists.
4602        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4603
4604        app.activities.clear();
4605
4606        if (app.instrumentationClass != null) {
4607            Slog.w(TAG, "Crash of app " + app.processName
4608                  + " running instrumentation " + app.instrumentationClass);
4609            Bundle info = new Bundle();
4610            info.putString("shortMsg", "Process crashed.");
4611            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4612        }
4613
4614        if (!restarting) {
4615            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4616                // If there was nothing to resume, and we are not already
4617                // restarting this process, but there is a visible activity that
4618                // is hosted by the process...  then make sure all visible
4619                // activities are running, taking care of restarting this
4620                // process.
4621                if (hasVisibleActivities) {
4622                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4623                }
4624            }
4625        }
4626    }
4627
4628    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4629        IBinder threadBinder = thread.asBinder();
4630        // Find the application record.
4631        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4632            ProcessRecord rec = mLruProcesses.get(i);
4633            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4634                return i;
4635            }
4636        }
4637        return -1;
4638    }
4639
4640    final ProcessRecord getRecordForAppLocked(
4641            IApplicationThread thread) {
4642        if (thread == null) {
4643            return null;
4644        }
4645
4646        int appIndex = getLRURecordIndexForAppLocked(thread);
4647        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4648    }
4649
4650    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4651        // If there are no longer any background processes running,
4652        // and the app that died was not running instrumentation,
4653        // then tell everyone we are now low on memory.
4654        boolean haveBg = false;
4655        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4656            ProcessRecord rec = mLruProcesses.get(i);
4657            if (rec.thread != null
4658                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4659                haveBg = true;
4660                break;
4661            }
4662        }
4663
4664        if (!haveBg) {
4665            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4666            if (doReport) {
4667                long now = SystemClock.uptimeMillis();
4668                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4669                    doReport = false;
4670                } else {
4671                    mLastMemUsageReportTime = now;
4672                }
4673            }
4674            final ArrayList<ProcessMemInfo> memInfos
4675                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4676            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4677            long now = SystemClock.uptimeMillis();
4678            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4679                ProcessRecord rec = mLruProcesses.get(i);
4680                if (rec == dyingProc || rec.thread == null) {
4681                    continue;
4682                }
4683                if (doReport) {
4684                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4685                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4686                }
4687                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4688                    // The low memory report is overriding any current
4689                    // state for a GC request.  Make sure to do
4690                    // heavy/important/visible/foreground processes first.
4691                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4692                        rec.lastRequestedGc = 0;
4693                    } else {
4694                        rec.lastRequestedGc = rec.lastLowMemory;
4695                    }
4696                    rec.reportLowMemory = true;
4697                    rec.lastLowMemory = now;
4698                    mProcessesToGc.remove(rec);
4699                    addProcessToGcListLocked(rec);
4700                }
4701            }
4702            if (doReport) {
4703                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4704                mHandler.sendMessage(msg);
4705            }
4706            scheduleAppGcsLocked();
4707        }
4708    }
4709
4710    final void appDiedLocked(ProcessRecord app) {
4711       appDiedLocked(app, app.pid, app.thread);
4712    }
4713
4714    final void appDiedLocked(ProcessRecord app, int pid,
4715            IApplicationThread thread) {
4716
4717        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4718        synchronized (stats) {
4719            stats.noteProcessDiedLocked(app.info.uid, pid);
4720        }
4721
4722        Process.killProcessGroup(app.info.uid, pid);
4723
4724        // Clean up already done if the process has been re-started.
4725        if (app.pid == pid && app.thread != null &&
4726                app.thread.asBinder() == thread.asBinder()) {
4727            boolean doLowMem = app.instrumentationClass == null;
4728            boolean doOomAdj = doLowMem;
4729            if (!app.killedByAm) {
4730                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4731                        + ") has died.");
4732                mAllowLowerMemLevel = true;
4733            } else {
4734                // Note that we always want to do oom adj to update our state with the
4735                // new number of procs.
4736                mAllowLowerMemLevel = false;
4737                doLowMem = false;
4738            }
4739            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4740            if (DEBUG_CLEANUP) Slog.v(
4741                TAG, "Dying app: " + app + ", pid: " + pid
4742                + ", thread: " + thread.asBinder());
4743            handleAppDiedLocked(app, false, true);
4744
4745            if (doOomAdj) {
4746                updateOomAdjLocked();
4747            }
4748            if (doLowMem) {
4749                doLowMemReportIfNeededLocked(app);
4750            }
4751        } else if (app.pid != pid) {
4752            // A new process has already been started.
4753            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4754                    + ") has died and restarted (pid " + app.pid + ").");
4755            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4756        } else if (DEBUG_PROCESSES) {
4757            Slog.d(TAG, "Received spurious death notification for thread "
4758                    + thread.asBinder());
4759        }
4760    }
4761
4762    /**
4763     * If a stack trace dump file is configured, dump process stack traces.
4764     * @param clearTraces causes the dump file to be erased prior to the new
4765     *    traces being written, if true; when false, the new traces will be
4766     *    appended to any existing file content.
4767     * @param firstPids of dalvik VM processes to dump stack traces for first
4768     * @param lastPids of dalvik VM processes to dump stack traces for last
4769     * @param nativeProcs optional list of native process names to dump stack crawls
4770     * @return file containing stack traces, or null if no dump file is configured
4771     */
4772    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4773            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4774        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4775        if (tracesPath == null || tracesPath.length() == 0) {
4776            return null;
4777        }
4778
4779        File tracesFile = new File(tracesPath);
4780        try {
4781            File tracesDir = tracesFile.getParentFile();
4782            if (!tracesDir.exists()) {
4783                tracesFile.mkdirs();
4784                if (!SELinux.restorecon(tracesDir)) {
4785                    return null;
4786                }
4787            }
4788            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4789
4790            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4791            tracesFile.createNewFile();
4792            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4793        } catch (IOException e) {
4794            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4795            return null;
4796        }
4797
4798        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4799        return tracesFile;
4800    }
4801
4802    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4803            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4804        // Use a FileObserver to detect when traces finish writing.
4805        // The order of traces is considered important to maintain for legibility.
4806        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4807            @Override
4808            public synchronized void onEvent(int event, String path) { notify(); }
4809        };
4810
4811        try {
4812            observer.startWatching();
4813
4814            // First collect all of the stacks of the most important pids.
4815            if (firstPids != null) {
4816                try {
4817                    int num = firstPids.size();
4818                    for (int i = 0; i < num; i++) {
4819                        synchronized (observer) {
4820                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4821                            observer.wait(200);  // Wait for write-close, give up after 200msec
4822                        }
4823                    }
4824                } catch (InterruptedException e) {
4825                    Log.wtf(TAG, e);
4826                }
4827            }
4828
4829            // Next collect the stacks of the native pids
4830            if (nativeProcs != null) {
4831                int[] pids = Process.getPidsForCommands(nativeProcs);
4832                if (pids != null) {
4833                    for (int pid : pids) {
4834                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4835                    }
4836                }
4837            }
4838
4839            // Lastly, measure CPU usage.
4840            if (processCpuTracker != null) {
4841                processCpuTracker.init();
4842                System.gc();
4843                processCpuTracker.update();
4844                try {
4845                    synchronized (processCpuTracker) {
4846                        processCpuTracker.wait(500); // measure over 1/2 second.
4847                    }
4848                } catch (InterruptedException e) {
4849                }
4850                processCpuTracker.update();
4851
4852                // We'll take the stack crawls of just the top apps using CPU.
4853                final int N = processCpuTracker.countWorkingStats();
4854                int numProcs = 0;
4855                for (int i=0; i<N && numProcs<5; i++) {
4856                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4857                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4858                        numProcs++;
4859                        try {
4860                            synchronized (observer) {
4861                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4862                                observer.wait(200);  // Wait for write-close, give up after 200msec
4863                            }
4864                        } catch (InterruptedException e) {
4865                            Log.wtf(TAG, e);
4866                        }
4867
4868                    }
4869                }
4870            }
4871        } finally {
4872            observer.stopWatching();
4873        }
4874    }
4875
4876    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4877        if (true || IS_USER_BUILD) {
4878            return;
4879        }
4880        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4881        if (tracesPath == null || tracesPath.length() == 0) {
4882            return;
4883        }
4884
4885        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4886        StrictMode.allowThreadDiskWrites();
4887        try {
4888            final File tracesFile = new File(tracesPath);
4889            final File tracesDir = tracesFile.getParentFile();
4890            final File tracesTmp = new File(tracesDir, "__tmp__");
4891            try {
4892                if (!tracesDir.exists()) {
4893                    tracesFile.mkdirs();
4894                    if (!SELinux.restorecon(tracesDir.getPath())) {
4895                        return;
4896                    }
4897                }
4898                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4899
4900                if (tracesFile.exists()) {
4901                    tracesTmp.delete();
4902                    tracesFile.renameTo(tracesTmp);
4903                }
4904                StringBuilder sb = new StringBuilder();
4905                Time tobj = new Time();
4906                tobj.set(System.currentTimeMillis());
4907                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4908                sb.append(": ");
4909                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4910                sb.append(" since ");
4911                sb.append(msg);
4912                FileOutputStream fos = new FileOutputStream(tracesFile);
4913                fos.write(sb.toString().getBytes());
4914                if (app == null) {
4915                    fos.write("\n*** No application process!".getBytes());
4916                }
4917                fos.close();
4918                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4919            } catch (IOException e) {
4920                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4921                return;
4922            }
4923
4924            if (app != null) {
4925                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4926                firstPids.add(app.pid);
4927                dumpStackTraces(tracesPath, firstPids, null, null, null);
4928            }
4929
4930            File lastTracesFile = null;
4931            File curTracesFile = null;
4932            for (int i=9; i>=0; i--) {
4933                String name = String.format(Locale.US, "slow%02d.txt", i);
4934                curTracesFile = new File(tracesDir, name);
4935                if (curTracesFile.exists()) {
4936                    if (lastTracesFile != null) {
4937                        curTracesFile.renameTo(lastTracesFile);
4938                    } else {
4939                        curTracesFile.delete();
4940                    }
4941                }
4942                lastTracesFile = curTracesFile;
4943            }
4944            tracesFile.renameTo(curTracesFile);
4945            if (tracesTmp.exists()) {
4946                tracesTmp.renameTo(tracesFile);
4947            }
4948        } finally {
4949            StrictMode.setThreadPolicy(oldPolicy);
4950        }
4951    }
4952
4953    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4954            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4955        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4956        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4957
4958        if (mController != null) {
4959            try {
4960                // 0 == continue, -1 = kill process immediately
4961                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4962                if (res < 0 && app.pid != MY_PID) {
4963                    app.kill("anr", true);
4964                }
4965            } catch (RemoteException e) {
4966                mController = null;
4967                Watchdog.getInstance().setActivityController(null);
4968            }
4969        }
4970
4971        long anrTime = SystemClock.uptimeMillis();
4972        if (MONITOR_CPU_USAGE) {
4973            updateCpuStatsNow();
4974        }
4975
4976        synchronized (this) {
4977            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4978            if (mShuttingDown) {
4979                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4980                return;
4981            } else if (app.notResponding) {
4982                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4983                return;
4984            } else if (app.crashing) {
4985                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4986                return;
4987            }
4988
4989            // In case we come through here for the same app before completing
4990            // this one, mark as anring now so we will bail out.
4991            app.notResponding = true;
4992
4993            // Log the ANR to the event log.
4994            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4995                    app.processName, app.info.flags, annotation);
4996
4997            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4998            firstPids.add(app.pid);
4999
5000            int parentPid = app.pid;
5001            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5002            if (parentPid != app.pid) firstPids.add(parentPid);
5003
5004            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5005
5006            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5007                ProcessRecord r = mLruProcesses.get(i);
5008                if (r != null && r.thread != null) {
5009                    int pid = r.pid;
5010                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5011                        if (r.persistent) {
5012                            firstPids.add(pid);
5013                        } else {
5014                            lastPids.put(pid, Boolean.TRUE);
5015                        }
5016                    }
5017                }
5018            }
5019        }
5020
5021        // Log the ANR to the main log.
5022        StringBuilder info = new StringBuilder();
5023        info.setLength(0);
5024        info.append("ANR in ").append(app.processName);
5025        if (activity != null && activity.shortComponentName != null) {
5026            info.append(" (").append(activity.shortComponentName).append(")");
5027        }
5028        info.append("\n");
5029        info.append("PID: ").append(app.pid).append("\n");
5030        if (annotation != null) {
5031            info.append("Reason: ").append(annotation).append("\n");
5032        }
5033        if (parent != null && parent != activity) {
5034            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5035        }
5036
5037        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5038
5039        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5040                NATIVE_STACKS_OF_INTEREST);
5041
5042        String cpuInfo = null;
5043        if (MONITOR_CPU_USAGE) {
5044            updateCpuStatsNow();
5045            synchronized (mProcessCpuThread) {
5046                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5047            }
5048            info.append(processCpuTracker.printCurrentLoad());
5049            info.append(cpuInfo);
5050        }
5051
5052        info.append(processCpuTracker.printCurrentState(anrTime));
5053
5054        Slog.e(TAG, info.toString());
5055        if (tracesFile == null) {
5056            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5057            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5058        }
5059
5060        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5061                cpuInfo, tracesFile, null);
5062
5063        if (mController != null) {
5064            try {
5065                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5066                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5067                if (res != 0) {
5068                    if (res < 0 && app.pid != MY_PID) {
5069                        app.kill("anr", true);
5070                    } else {
5071                        synchronized (this) {
5072                            mServices.scheduleServiceTimeoutLocked(app);
5073                        }
5074                    }
5075                    return;
5076                }
5077            } catch (RemoteException e) {
5078                mController = null;
5079                Watchdog.getInstance().setActivityController(null);
5080            }
5081        }
5082
5083        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5084        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5085                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5086
5087        synchronized (this) {
5088            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5089                app.kill("bg anr", true);
5090                return;
5091            }
5092
5093            // Set the app's notResponding state, and look up the errorReportReceiver
5094            makeAppNotRespondingLocked(app,
5095                    activity != null ? activity.shortComponentName : null,
5096                    annotation != null ? "ANR " + annotation : "ANR",
5097                    info.toString());
5098
5099            // Bring up the infamous App Not Responding dialog
5100            Message msg = Message.obtain();
5101            HashMap<String, Object> map = new HashMap<String, Object>();
5102            msg.what = SHOW_NOT_RESPONDING_MSG;
5103            msg.obj = map;
5104            msg.arg1 = aboveSystem ? 1 : 0;
5105            map.put("app", app);
5106            if (activity != null) {
5107                map.put("activity", activity);
5108            }
5109
5110            mHandler.sendMessage(msg);
5111        }
5112    }
5113
5114    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5115        if (!mLaunchWarningShown) {
5116            mLaunchWarningShown = true;
5117            mHandler.post(new Runnable() {
5118                @Override
5119                public void run() {
5120                    synchronized (ActivityManagerService.this) {
5121                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5122                        d.show();
5123                        mHandler.postDelayed(new Runnable() {
5124                            @Override
5125                            public void run() {
5126                                synchronized (ActivityManagerService.this) {
5127                                    d.dismiss();
5128                                    mLaunchWarningShown = false;
5129                                }
5130                            }
5131                        }, 4000);
5132                    }
5133                }
5134            });
5135        }
5136    }
5137
5138    @Override
5139    public boolean clearApplicationUserData(final String packageName,
5140            final IPackageDataObserver observer, int userId) {
5141        enforceNotIsolatedCaller("clearApplicationUserData");
5142        int uid = Binder.getCallingUid();
5143        int pid = Binder.getCallingPid();
5144        userId = handleIncomingUser(pid, uid,
5145                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5146        long callingId = Binder.clearCallingIdentity();
5147        try {
5148            IPackageManager pm = AppGlobals.getPackageManager();
5149            int pkgUid = -1;
5150            synchronized(this) {
5151                try {
5152                    pkgUid = pm.getPackageUid(packageName, userId);
5153                } catch (RemoteException e) {
5154                }
5155                if (pkgUid == -1) {
5156                    Slog.w(TAG, "Invalid packageName: " + packageName);
5157                    if (observer != null) {
5158                        try {
5159                            observer.onRemoveCompleted(packageName, false);
5160                        } catch (RemoteException e) {
5161                            Slog.i(TAG, "Observer no longer exists.");
5162                        }
5163                    }
5164                    return false;
5165                }
5166                if (uid == pkgUid || checkComponentPermission(
5167                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5168                        pid, uid, -1, true)
5169                        == PackageManager.PERMISSION_GRANTED) {
5170                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5171                } else {
5172                    throw new SecurityException("PID " + pid + " does not have permission "
5173                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5174                                    + " of package " + packageName);
5175                }
5176
5177                // Remove all tasks match the cleared application package and user
5178                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5179                    final TaskRecord tr = mRecentTasks.get(i);
5180                    final String taskPackageName =
5181                            tr.getBaseIntent().getComponent().getPackageName();
5182                    if (tr.userId != userId) continue;
5183                    if (!taskPackageName.equals(packageName)) continue;
5184                    removeTaskByIdLocked(tr.taskId, 0);
5185                }
5186            }
5187
5188            try {
5189                // Clear application user data
5190                pm.clearApplicationUserData(packageName, observer, userId);
5191
5192                synchronized(this) {
5193                    // Remove all permissions granted from/to this package
5194                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5195                }
5196
5197                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5198                        Uri.fromParts("package", packageName, null));
5199                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5200                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5201                        null, null, 0, null, null, null, false, false, userId);
5202            } catch (RemoteException e) {
5203            }
5204        } finally {
5205            Binder.restoreCallingIdentity(callingId);
5206        }
5207        return true;
5208    }
5209
5210    @Override
5211    public void killBackgroundProcesses(final String packageName, int userId) {
5212        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5213                != PackageManager.PERMISSION_GRANTED &&
5214                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5215                        != PackageManager.PERMISSION_GRANTED) {
5216            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5217                    + Binder.getCallingPid()
5218                    + ", uid=" + Binder.getCallingUid()
5219                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5220            Slog.w(TAG, msg);
5221            throw new SecurityException(msg);
5222        }
5223
5224        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5225                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5226        long callingId = Binder.clearCallingIdentity();
5227        try {
5228            IPackageManager pm = AppGlobals.getPackageManager();
5229            synchronized(this) {
5230                int appId = -1;
5231                try {
5232                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5233                } catch (RemoteException e) {
5234                }
5235                if (appId == -1) {
5236                    Slog.w(TAG, "Invalid packageName: " + packageName);
5237                    return;
5238                }
5239                killPackageProcessesLocked(packageName, appId, userId,
5240                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5241            }
5242        } finally {
5243            Binder.restoreCallingIdentity(callingId);
5244        }
5245    }
5246
5247    @Override
5248    public void killAllBackgroundProcesses() {
5249        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5250                != PackageManager.PERMISSION_GRANTED) {
5251            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5252                    + Binder.getCallingPid()
5253                    + ", uid=" + Binder.getCallingUid()
5254                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5255            Slog.w(TAG, msg);
5256            throw new SecurityException(msg);
5257        }
5258
5259        long callingId = Binder.clearCallingIdentity();
5260        try {
5261            synchronized(this) {
5262                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5263                final int NP = mProcessNames.getMap().size();
5264                for (int ip=0; ip<NP; ip++) {
5265                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5266                    final int NA = apps.size();
5267                    for (int ia=0; ia<NA; ia++) {
5268                        ProcessRecord app = apps.valueAt(ia);
5269                        if (app.persistent) {
5270                            // we don't kill persistent processes
5271                            continue;
5272                        }
5273                        if (app.removed) {
5274                            procs.add(app);
5275                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5276                            app.removed = true;
5277                            procs.add(app);
5278                        }
5279                    }
5280                }
5281
5282                int N = procs.size();
5283                for (int i=0; i<N; i++) {
5284                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5285                }
5286                mAllowLowerMemLevel = true;
5287                updateOomAdjLocked();
5288                doLowMemReportIfNeededLocked(null);
5289            }
5290        } finally {
5291            Binder.restoreCallingIdentity(callingId);
5292        }
5293    }
5294
5295    @Override
5296    public void forceStopPackage(final String packageName, int userId) {
5297        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5298                != PackageManager.PERMISSION_GRANTED) {
5299            String msg = "Permission Denial: forceStopPackage() from pid="
5300                    + Binder.getCallingPid()
5301                    + ", uid=" + Binder.getCallingUid()
5302                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5303            Slog.w(TAG, msg);
5304            throw new SecurityException(msg);
5305        }
5306        final int callingPid = Binder.getCallingPid();
5307        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5308                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5309        long callingId = Binder.clearCallingIdentity();
5310        try {
5311            IPackageManager pm = AppGlobals.getPackageManager();
5312            synchronized(this) {
5313                int[] users = userId == UserHandle.USER_ALL
5314                        ? getUsersLocked() : new int[] { userId };
5315                for (int user : users) {
5316                    int pkgUid = -1;
5317                    try {
5318                        pkgUid = pm.getPackageUid(packageName, user);
5319                    } catch (RemoteException e) {
5320                    }
5321                    if (pkgUid == -1) {
5322                        Slog.w(TAG, "Invalid packageName: " + packageName);
5323                        continue;
5324                    }
5325                    try {
5326                        pm.setPackageStoppedState(packageName, true, user);
5327                    } catch (RemoteException e) {
5328                    } catch (IllegalArgumentException e) {
5329                        Slog.w(TAG, "Failed trying to unstop package "
5330                                + packageName + ": " + e);
5331                    }
5332                    if (isUserRunningLocked(user, false)) {
5333                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5334                    }
5335                }
5336            }
5337        } finally {
5338            Binder.restoreCallingIdentity(callingId);
5339        }
5340    }
5341
5342    @Override
5343    public void addPackageDependency(String packageName) {
5344        synchronized (this) {
5345            int callingPid = Binder.getCallingPid();
5346            if (callingPid == Process.myPid()) {
5347                //  Yeah, um, no.
5348                Slog.w(TAG, "Can't addPackageDependency on system process");
5349                return;
5350            }
5351            ProcessRecord proc;
5352            synchronized (mPidsSelfLocked) {
5353                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5354            }
5355            if (proc != null) {
5356                if (proc.pkgDeps == null) {
5357                    proc.pkgDeps = new ArraySet<String>(1);
5358                }
5359                proc.pkgDeps.add(packageName);
5360            }
5361        }
5362    }
5363
5364    /*
5365     * The pkg name and app id have to be specified.
5366     */
5367    @Override
5368    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5369        if (pkg == null) {
5370            return;
5371        }
5372        // Make sure the uid is valid.
5373        if (appid < 0) {
5374            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5375            return;
5376        }
5377        int callerUid = Binder.getCallingUid();
5378        // Only the system server can kill an application
5379        if (callerUid == Process.SYSTEM_UID) {
5380            // Post an aysnc message to kill the application
5381            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5382            msg.arg1 = appid;
5383            msg.arg2 = 0;
5384            Bundle bundle = new Bundle();
5385            bundle.putString("pkg", pkg);
5386            bundle.putString("reason", reason);
5387            msg.obj = bundle;
5388            mHandler.sendMessage(msg);
5389        } else {
5390            throw new SecurityException(callerUid + " cannot kill pkg: " +
5391                    pkg);
5392        }
5393    }
5394
5395    @Override
5396    public void closeSystemDialogs(String reason) {
5397        enforceNotIsolatedCaller("closeSystemDialogs");
5398
5399        final int pid = Binder.getCallingPid();
5400        final int uid = Binder.getCallingUid();
5401        final long origId = Binder.clearCallingIdentity();
5402        try {
5403            synchronized (this) {
5404                // Only allow this from foreground processes, so that background
5405                // applications can't abuse it to prevent system UI from being shown.
5406                if (uid >= Process.FIRST_APPLICATION_UID) {
5407                    ProcessRecord proc;
5408                    synchronized (mPidsSelfLocked) {
5409                        proc = mPidsSelfLocked.get(pid);
5410                    }
5411                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5412                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5413                                + " from background process " + proc);
5414                        return;
5415                    }
5416                }
5417                closeSystemDialogsLocked(reason);
5418            }
5419        } finally {
5420            Binder.restoreCallingIdentity(origId);
5421        }
5422    }
5423
5424    void closeSystemDialogsLocked(String reason) {
5425        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5426        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5427                | Intent.FLAG_RECEIVER_FOREGROUND);
5428        if (reason != null) {
5429            intent.putExtra("reason", reason);
5430        }
5431        mWindowManager.closeSystemDialogs(reason);
5432
5433        mStackSupervisor.closeSystemDialogsLocked();
5434
5435        broadcastIntentLocked(null, null, intent, null,
5436                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5437                Process.SYSTEM_UID, UserHandle.USER_ALL);
5438    }
5439
5440    @Override
5441    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5442        enforceNotIsolatedCaller("getProcessMemoryInfo");
5443        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5444        for (int i=pids.length-1; i>=0; i--) {
5445            ProcessRecord proc;
5446            int oomAdj;
5447            synchronized (this) {
5448                synchronized (mPidsSelfLocked) {
5449                    proc = mPidsSelfLocked.get(pids[i]);
5450                    oomAdj = proc != null ? proc.setAdj : 0;
5451                }
5452            }
5453            infos[i] = new Debug.MemoryInfo();
5454            Debug.getMemoryInfo(pids[i], infos[i]);
5455            if (proc != null) {
5456                synchronized (this) {
5457                    if (proc.thread != null && proc.setAdj == oomAdj) {
5458                        // Record this for posterity if the process has been stable.
5459                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5460                                infos[i].getTotalUss(), false, proc.pkgList);
5461                    }
5462                }
5463            }
5464        }
5465        return infos;
5466    }
5467
5468    @Override
5469    public long[] getProcessPss(int[] pids) {
5470        enforceNotIsolatedCaller("getProcessPss");
5471        long[] pss = new long[pids.length];
5472        for (int i=pids.length-1; i>=0; i--) {
5473            ProcessRecord proc;
5474            int oomAdj;
5475            synchronized (this) {
5476                synchronized (mPidsSelfLocked) {
5477                    proc = mPidsSelfLocked.get(pids[i]);
5478                    oomAdj = proc != null ? proc.setAdj : 0;
5479                }
5480            }
5481            long[] tmpUss = new long[1];
5482            pss[i] = Debug.getPss(pids[i], tmpUss);
5483            if (proc != null) {
5484                synchronized (this) {
5485                    if (proc.thread != null && proc.setAdj == oomAdj) {
5486                        // Record this for posterity if the process has been stable.
5487                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5488                    }
5489                }
5490            }
5491        }
5492        return pss;
5493    }
5494
5495    @Override
5496    public void killApplicationProcess(String processName, int uid) {
5497        if (processName == null) {
5498            return;
5499        }
5500
5501        int callerUid = Binder.getCallingUid();
5502        // Only the system server can kill an application
5503        if (callerUid == Process.SYSTEM_UID) {
5504            synchronized (this) {
5505                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5506                if (app != null && app.thread != null) {
5507                    try {
5508                        app.thread.scheduleSuicide();
5509                    } catch (RemoteException e) {
5510                        // If the other end already died, then our work here is done.
5511                    }
5512                } else {
5513                    Slog.w(TAG, "Process/uid not found attempting kill of "
5514                            + processName + " / " + uid);
5515                }
5516            }
5517        } else {
5518            throw new SecurityException(callerUid + " cannot kill app process: " +
5519                    processName);
5520        }
5521    }
5522
5523    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5524        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5525                false, true, false, false, UserHandle.getUserId(uid), reason);
5526        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5527                Uri.fromParts("package", packageName, null));
5528        if (!mProcessesReady) {
5529            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5530                    | Intent.FLAG_RECEIVER_FOREGROUND);
5531        }
5532        intent.putExtra(Intent.EXTRA_UID, uid);
5533        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5534        broadcastIntentLocked(null, null, intent,
5535                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5536                false, false,
5537                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5538    }
5539
5540    private void forceStopUserLocked(int userId, String reason) {
5541        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5542        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5543        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5544                | Intent.FLAG_RECEIVER_FOREGROUND);
5545        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5546        broadcastIntentLocked(null, null, intent,
5547                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5548                false, false,
5549                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5550    }
5551
5552    private final boolean killPackageProcessesLocked(String packageName, int appId,
5553            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5554            boolean doit, boolean evenPersistent, String reason) {
5555        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5556
5557        // Remove all processes this package may have touched: all with the
5558        // same UID (except for the system or root user), and all whose name
5559        // matches the package name.
5560        final int NP = mProcessNames.getMap().size();
5561        for (int ip=0; ip<NP; ip++) {
5562            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5563            final int NA = apps.size();
5564            for (int ia=0; ia<NA; ia++) {
5565                ProcessRecord app = apps.valueAt(ia);
5566                if (app.persistent && !evenPersistent) {
5567                    // we don't kill persistent processes
5568                    continue;
5569                }
5570                if (app.removed) {
5571                    if (doit) {
5572                        procs.add(app);
5573                    }
5574                    continue;
5575                }
5576
5577                // Skip process if it doesn't meet our oom adj requirement.
5578                if (app.setAdj < minOomAdj) {
5579                    continue;
5580                }
5581
5582                // If no package is specified, we call all processes under the
5583                // give user id.
5584                if (packageName == null) {
5585                    if (app.userId != userId) {
5586                        continue;
5587                    }
5588                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5589                        continue;
5590                    }
5591                // Package has been specified, we want to hit all processes
5592                // that match it.  We need to qualify this by the processes
5593                // that are running under the specified app and user ID.
5594                } else {
5595                    final boolean isDep = app.pkgDeps != null
5596                            && app.pkgDeps.contains(packageName);
5597                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5598                        continue;
5599                    }
5600                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5601                        continue;
5602                    }
5603                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5604                        continue;
5605                    }
5606                }
5607
5608                // Process has passed all conditions, kill it!
5609                if (!doit) {
5610                    return true;
5611                }
5612                app.removed = true;
5613                procs.add(app);
5614            }
5615        }
5616
5617        int N = procs.size();
5618        for (int i=0; i<N; i++) {
5619            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5620        }
5621        updateOomAdjLocked();
5622        return N > 0;
5623    }
5624
5625    private final boolean forceStopPackageLocked(String name, int appId,
5626            boolean callerWillRestart, boolean purgeCache, boolean doit,
5627            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5628        int i;
5629        int N;
5630
5631        if (userId == UserHandle.USER_ALL && name == null) {
5632            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5633        }
5634
5635        if (appId < 0 && name != null) {
5636            try {
5637                appId = UserHandle.getAppId(
5638                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5639            } catch (RemoteException e) {
5640            }
5641        }
5642
5643        if (doit) {
5644            if (name != null) {
5645                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5646                        + " user=" + userId + ": " + reason);
5647            } else {
5648                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5649            }
5650
5651            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5652            for (int ip=pmap.size()-1; ip>=0; ip--) {
5653                SparseArray<Long> ba = pmap.valueAt(ip);
5654                for (i=ba.size()-1; i>=0; i--) {
5655                    boolean remove = false;
5656                    final int entUid = ba.keyAt(i);
5657                    if (name != null) {
5658                        if (userId == UserHandle.USER_ALL) {
5659                            if (UserHandle.getAppId(entUid) == appId) {
5660                                remove = true;
5661                            }
5662                        } else {
5663                            if (entUid == UserHandle.getUid(userId, appId)) {
5664                                remove = true;
5665                            }
5666                        }
5667                    } else if (UserHandle.getUserId(entUid) == userId) {
5668                        remove = true;
5669                    }
5670                    if (remove) {
5671                        ba.removeAt(i);
5672                    }
5673                }
5674                if (ba.size() == 0) {
5675                    pmap.removeAt(ip);
5676                }
5677            }
5678        }
5679
5680        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5681                -100, callerWillRestart, true, doit, evenPersistent,
5682                name == null ? ("stop user " + userId) : ("stop " + name));
5683
5684        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5685            if (!doit) {
5686                return true;
5687            }
5688            didSomething = true;
5689        }
5690
5691        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5692            if (!doit) {
5693                return true;
5694            }
5695            didSomething = true;
5696        }
5697
5698        if (name == null) {
5699            // Remove all sticky broadcasts from this user.
5700            mStickyBroadcasts.remove(userId);
5701        }
5702
5703        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5704        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5705                userId, providers)) {
5706            if (!doit) {
5707                return true;
5708            }
5709            didSomething = true;
5710        }
5711        N = providers.size();
5712        for (i=0; i<N; i++) {
5713            removeDyingProviderLocked(null, providers.get(i), true);
5714        }
5715
5716        // Remove transient permissions granted from/to this package/user
5717        removeUriPermissionsForPackageLocked(name, userId, false);
5718
5719        if (name == null || uninstalling) {
5720            // Remove pending intents.  For now we only do this when force
5721            // stopping users, because we have some problems when doing this
5722            // for packages -- app widgets are not currently cleaned up for
5723            // such packages, so they can be left with bad pending intents.
5724            if (mIntentSenderRecords.size() > 0) {
5725                Iterator<WeakReference<PendingIntentRecord>> it
5726                        = mIntentSenderRecords.values().iterator();
5727                while (it.hasNext()) {
5728                    WeakReference<PendingIntentRecord> wpir = it.next();
5729                    if (wpir == null) {
5730                        it.remove();
5731                        continue;
5732                    }
5733                    PendingIntentRecord pir = wpir.get();
5734                    if (pir == null) {
5735                        it.remove();
5736                        continue;
5737                    }
5738                    if (name == null) {
5739                        // Stopping user, remove all objects for the user.
5740                        if (pir.key.userId != userId) {
5741                            // Not the same user, skip it.
5742                            continue;
5743                        }
5744                    } else {
5745                        if (UserHandle.getAppId(pir.uid) != appId) {
5746                            // Different app id, skip it.
5747                            continue;
5748                        }
5749                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5750                            // Different user, skip it.
5751                            continue;
5752                        }
5753                        if (!pir.key.packageName.equals(name)) {
5754                            // Different package, skip it.
5755                            continue;
5756                        }
5757                    }
5758                    if (!doit) {
5759                        return true;
5760                    }
5761                    didSomething = true;
5762                    it.remove();
5763                    pir.canceled = true;
5764                    if (pir.key.activity != null) {
5765                        pir.key.activity.pendingResults.remove(pir.ref);
5766                    }
5767                }
5768            }
5769        }
5770
5771        if (doit) {
5772            if (purgeCache && name != null) {
5773                AttributeCache ac = AttributeCache.instance();
5774                if (ac != null) {
5775                    ac.removePackage(name);
5776                }
5777            }
5778            if (mBooted) {
5779                mStackSupervisor.resumeTopActivitiesLocked();
5780                mStackSupervisor.scheduleIdleLocked();
5781            }
5782        }
5783
5784        return didSomething;
5785    }
5786
5787    private final boolean removeProcessLocked(ProcessRecord app,
5788            boolean callerWillRestart, boolean allowRestart, String reason) {
5789        final String name = app.processName;
5790        final int uid = app.uid;
5791        if (DEBUG_PROCESSES) Slog.d(
5792            TAG, "Force removing proc " + app.toShortString() + " (" + name
5793            + "/" + uid + ")");
5794
5795        mProcessNames.remove(name, uid);
5796        mIsolatedProcesses.remove(app.uid);
5797        if (mHeavyWeightProcess == app) {
5798            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5799                    mHeavyWeightProcess.userId, 0));
5800            mHeavyWeightProcess = null;
5801        }
5802        boolean needRestart = false;
5803        if (app.pid > 0 && app.pid != MY_PID) {
5804            int pid = app.pid;
5805            synchronized (mPidsSelfLocked) {
5806                mPidsSelfLocked.remove(pid);
5807                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5808            }
5809            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5810            if (app.isolated) {
5811                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5812            }
5813            app.kill(reason, true);
5814            handleAppDiedLocked(app, true, allowRestart);
5815            removeLruProcessLocked(app);
5816
5817            if (app.persistent && !app.isolated) {
5818                if (!callerWillRestart) {
5819                    addAppLocked(app.info, false, null /* ABI override */);
5820                } else {
5821                    needRestart = true;
5822                }
5823            }
5824        } else {
5825            mRemovedProcesses.add(app);
5826        }
5827
5828        return needRestart;
5829    }
5830
5831    private final void processStartTimedOutLocked(ProcessRecord app) {
5832        final int pid = app.pid;
5833        boolean gone = false;
5834        synchronized (mPidsSelfLocked) {
5835            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5836            if (knownApp != null && knownApp.thread == null) {
5837                mPidsSelfLocked.remove(pid);
5838                gone = true;
5839            }
5840        }
5841
5842        if (gone) {
5843            Slog.w(TAG, "Process " + app + " failed to attach");
5844            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5845                    pid, app.uid, app.processName);
5846            mProcessNames.remove(app.processName, app.uid);
5847            mIsolatedProcesses.remove(app.uid);
5848            if (mHeavyWeightProcess == app) {
5849                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5850                        mHeavyWeightProcess.userId, 0));
5851                mHeavyWeightProcess = null;
5852            }
5853            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5854            if (app.isolated) {
5855                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5856            }
5857            // Take care of any launching providers waiting for this process.
5858            checkAppInLaunchingProvidersLocked(app, true);
5859            // Take care of any services that are waiting for the process.
5860            mServices.processStartTimedOutLocked(app);
5861            app.kill("start timeout", true);
5862            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5863                Slog.w(TAG, "Unattached app died before backup, skipping");
5864                try {
5865                    IBackupManager bm = IBackupManager.Stub.asInterface(
5866                            ServiceManager.getService(Context.BACKUP_SERVICE));
5867                    bm.agentDisconnected(app.info.packageName);
5868                } catch (RemoteException e) {
5869                    // Can't happen; the backup manager is local
5870                }
5871            }
5872            if (isPendingBroadcastProcessLocked(pid)) {
5873                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5874                skipPendingBroadcastLocked(pid);
5875            }
5876        } else {
5877            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5878        }
5879    }
5880
5881    private final boolean attachApplicationLocked(IApplicationThread thread,
5882            int pid) {
5883
5884        // Find the application record that is being attached...  either via
5885        // the pid if we are running in multiple processes, or just pull the
5886        // next app record if we are emulating process with anonymous threads.
5887        ProcessRecord app;
5888        if (pid != MY_PID && pid >= 0) {
5889            synchronized (mPidsSelfLocked) {
5890                app = mPidsSelfLocked.get(pid);
5891            }
5892        } else {
5893            app = null;
5894        }
5895
5896        if (app == null) {
5897            Slog.w(TAG, "No pending application record for pid " + pid
5898                    + " (IApplicationThread " + thread + "); dropping process");
5899            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5900            if (pid > 0 && pid != MY_PID) {
5901                Process.killProcessQuiet(pid);
5902                //TODO: Process.killProcessGroup(app.info.uid, pid);
5903            } else {
5904                try {
5905                    thread.scheduleExit();
5906                } catch (Exception e) {
5907                    // Ignore exceptions.
5908                }
5909            }
5910            return false;
5911        }
5912
5913        // If this application record is still attached to a previous
5914        // process, clean it up now.
5915        if (app.thread != null) {
5916            handleAppDiedLocked(app, true, true);
5917        }
5918
5919        // Tell the process all about itself.
5920
5921        if (localLOGV) Slog.v(
5922                TAG, "Binding process pid " + pid + " to record " + app);
5923
5924        final String processName = app.processName;
5925        try {
5926            AppDeathRecipient adr = new AppDeathRecipient(
5927                    app, pid, thread);
5928            thread.asBinder().linkToDeath(adr, 0);
5929            app.deathRecipient = adr;
5930        } catch (RemoteException e) {
5931            app.resetPackageList(mProcessStats);
5932            startProcessLocked(app, "link fail", processName);
5933            return false;
5934        }
5935
5936        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5937
5938        app.makeActive(thread, mProcessStats);
5939        app.curAdj = app.setAdj = -100;
5940        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5941        app.forcingToForeground = null;
5942        updateProcessForegroundLocked(app, false, false);
5943        app.hasShownUi = false;
5944        app.debugging = false;
5945        app.cached = false;
5946
5947        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5948
5949        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5950        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5951
5952        if (!normalMode) {
5953            Slog.i(TAG, "Launching preboot mode app: " + app);
5954        }
5955
5956        if (localLOGV) Slog.v(
5957            TAG, "New app record " + app
5958            + " thread=" + thread.asBinder() + " pid=" + pid);
5959        try {
5960            int testMode = IApplicationThread.DEBUG_OFF;
5961            if (mDebugApp != null && mDebugApp.equals(processName)) {
5962                testMode = mWaitForDebugger
5963                    ? IApplicationThread.DEBUG_WAIT
5964                    : IApplicationThread.DEBUG_ON;
5965                app.debugging = true;
5966                if (mDebugTransient) {
5967                    mDebugApp = mOrigDebugApp;
5968                    mWaitForDebugger = mOrigWaitForDebugger;
5969                }
5970            }
5971            String profileFile = app.instrumentationProfileFile;
5972            ParcelFileDescriptor profileFd = null;
5973            boolean profileAutoStop = false;
5974            if (mProfileApp != null && mProfileApp.equals(processName)) {
5975                mProfileProc = app;
5976                profileFile = mProfileFile;
5977                profileFd = mProfileFd;
5978                profileAutoStop = mAutoStopProfiler;
5979            }
5980            boolean enableOpenGlTrace = false;
5981            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5982                enableOpenGlTrace = true;
5983                mOpenGlTraceApp = null;
5984            }
5985
5986            // If the app is being launched for restore or full backup, set it up specially
5987            boolean isRestrictedBackupMode = false;
5988            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5989                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5990                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5991                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5992            }
5993
5994            ensurePackageDexOpt(app.instrumentationInfo != null
5995                    ? app.instrumentationInfo.packageName
5996                    : app.info.packageName);
5997            if (app.instrumentationClass != null) {
5998                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5999            }
6000            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
6001                    + processName + " with config " + mConfiguration);
6002            ApplicationInfo appInfo = app.instrumentationInfo != null
6003                    ? app.instrumentationInfo : app.info;
6004            app.compat = compatibilityInfoForPackageLocked(appInfo);
6005            if (profileFd != null) {
6006                profileFd = profileFd.dup();
6007            }
6008            thread.bindApplication(processName, appInfo, providers,
6009                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
6010                    app.instrumentationArguments, app.instrumentationWatcher,
6011                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6012                    isRestrictedBackupMode || !normalMode, app.persistent,
6013                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
6014                    mCoreSettingsObserver.getCoreSettingsLocked());
6015            updateLruProcessLocked(app, false, null);
6016            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6017        } catch (Exception e) {
6018            // todo: Yikes!  What should we do?  For now we will try to
6019            // start another process, but that could easily get us in
6020            // an infinite loop of restarting processes...
6021            Slog.w(TAG, "Exception thrown during bind!", e);
6022
6023            app.resetPackageList(mProcessStats);
6024            app.unlinkDeathRecipient();
6025            startProcessLocked(app, "bind fail", processName);
6026            return false;
6027        }
6028
6029        // Remove this record from the list of starting applications.
6030        mPersistentStartingProcesses.remove(app);
6031        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6032                "Attach application locked removing on hold: " + app);
6033        mProcessesOnHold.remove(app);
6034
6035        boolean badApp = false;
6036        boolean didSomething = false;
6037
6038        // See if the top visible activity is waiting to run in this process...
6039        if (normalMode) {
6040            try {
6041                if (mStackSupervisor.attachApplicationLocked(app)) {
6042                    didSomething = true;
6043                }
6044            } catch (Exception e) {
6045                badApp = true;
6046            }
6047        }
6048
6049        // Find any services that should be running in this process...
6050        if (!badApp) {
6051            try {
6052                didSomething |= mServices.attachApplicationLocked(app, processName);
6053            } catch (Exception e) {
6054                badApp = true;
6055            }
6056        }
6057
6058        // Check if a next-broadcast receiver is in this process...
6059        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6060            try {
6061                didSomething |= sendPendingBroadcastsLocked(app);
6062            } catch (Exception e) {
6063                // If the app died trying to launch the receiver we declare it 'bad'
6064                badApp = true;
6065            }
6066        }
6067
6068        // Check whether the next backup agent is in this process...
6069        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6070            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6071            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6072            try {
6073                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6074                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6075                        mBackupTarget.backupMode);
6076            } catch (Exception e) {
6077                Slog.w(TAG, "Exception scheduling backup agent creation: ");
6078                e.printStackTrace();
6079            }
6080        }
6081
6082        if (badApp) {
6083            // todo: Also need to kill application to deal with all
6084            // kinds of exceptions.
6085            handleAppDiedLocked(app, false, true);
6086            return false;
6087        }
6088
6089        if (!didSomething) {
6090            updateOomAdjLocked();
6091        }
6092
6093        return true;
6094    }
6095
6096    @Override
6097    public final void attachApplication(IApplicationThread thread) {
6098        synchronized (this) {
6099            int callingPid = Binder.getCallingPid();
6100            final long origId = Binder.clearCallingIdentity();
6101            attachApplicationLocked(thread, callingPid);
6102            Binder.restoreCallingIdentity(origId);
6103        }
6104    }
6105
6106    @Override
6107    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6108        final long origId = Binder.clearCallingIdentity();
6109        synchronized (this) {
6110            ActivityStack stack = ActivityRecord.getStackLocked(token);
6111            if (stack != null) {
6112                ActivityRecord r =
6113                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6114                if (stopProfiling) {
6115                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6116                        try {
6117                            mProfileFd.close();
6118                        } catch (IOException e) {
6119                        }
6120                        clearProfilerLocked();
6121                    }
6122                }
6123            }
6124        }
6125        Binder.restoreCallingIdentity(origId);
6126    }
6127
6128    void postEnableScreenAfterBootLocked() {
6129        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
6130    }
6131
6132    void enableScreenAfterBoot() {
6133        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6134                SystemClock.uptimeMillis());
6135        mWindowManager.enableScreenAfterBoot();
6136
6137        synchronized (this) {
6138            updateEventDispatchingLocked();
6139        }
6140    }
6141
6142    @Override
6143    public void showBootMessage(final CharSequence msg, final boolean always) {
6144        enforceNotIsolatedCaller("showBootMessage");
6145        mWindowManager.showBootMessage(msg, always);
6146    }
6147
6148    @Override
6149    public void keyguardWaitingForActivityDrawn() {
6150        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6151        final long token = Binder.clearCallingIdentity();
6152        try {
6153            synchronized (this) {
6154                if (DEBUG_LOCKSCREEN) logLockScreen("");
6155                mWindowManager.keyguardWaitingForActivityDrawn();
6156            }
6157        } finally {
6158            Binder.restoreCallingIdentity(token);
6159        }
6160    }
6161
6162    final void finishBooting() {
6163        // Register receivers to handle package update events
6164        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
6165
6166        // Let system services know.
6167        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6168
6169        synchronized (this) {
6170            // Ensure that any processes we had put on hold are now started
6171            // up.
6172            final int NP = mProcessesOnHold.size();
6173            if (NP > 0) {
6174                ArrayList<ProcessRecord> procs =
6175                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6176                for (int ip=0; ip<NP; ip++) {
6177                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6178                            + procs.get(ip));
6179                    startProcessLocked(procs.get(ip), "on-hold", null);
6180                }
6181            }
6182
6183            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6184                // Start looking for apps that are abusing wake locks.
6185                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6186                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6187                // Tell anyone interested that we are done booting!
6188                SystemProperties.set("sys.boot_completed", "1");
6189                SystemProperties.set("dev.bootcomplete", "1");
6190                for (int i=0; i<mStartedUsers.size(); i++) {
6191                    UserStartedState uss = mStartedUsers.valueAt(i);
6192                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6193                        uss.mState = UserStartedState.STATE_RUNNING;
6194                        final int userId = mStartedUsers.keyAt(i);
6195                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6196                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6197                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6198                        broadcastIntentLocked(null, null, intent, null,
6199                                new IIntentReceiver.Stub() {
6200                                    @Override
6201                                    public void performReceive(Intent intent, int resultCode,
6202                                            String data, Bundle extras, boolean ordered,
6203                                            boolean sticky, int sendingUser) {
6204                                        synchronized (ActivityManagerService.this) {
6205                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6206                                                    true, false);
6207                                        }
6208                                    }
6209                                },
6210                                0, null, null,
6211                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6212                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6213                                userId);
6214                    }
6215                }
6216                scheduleStartProfilesLocked();
6217            }
6218        }
6219    }
6220
6221    final void ensureBootCompleted() {
6222        boolean booting;
6223        boolean enableScreen;
6224        synchronized (this) {
6225            booting = mBooting;
6226            mBooting = false;
6227            enableScreen = !mBooted;
6228            mBooted = true;
6229        }
6230
6231        if (booting) {
6232            finishBooting();
6233        }
6234
6235        if (enableScreen) {
6236            enableScreenAfterBoot();
6237        }
6238    }
6239
6240    @Override
6241    public final void activityResumed(IBinder token) {
6242        final long origId = Binder.clearCallingIdentity();
6243        synchronized(this) {
6244            ActivityStack stack = ActivityRecord.getStackLocked(token);
6245            if (stack != null) {
6246                ActivityRecord.activityResumedLocked(token);
6247            }
6248        }
6249        Binder.restoreCallingIdentity(origId);
6250    }
6251
6252    @Override
6253    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
6254        final long origId = Binder.clearCallingIdentity();
6255        synchronized(this) {
6256            ActivityStack stack = ActivityRecord.getStackLocked(token);
6257            if (stack != null) {
6258                stack.activityPausedLocked(token, false, persistentState);
6259            }
6260        }
6261        Binder.restoreCallingIdentity(origId);
6262    }
6263
6264    @Override
6265    public final void activityStopped(IBinder token, Bundle icicle,
6266            PersistableBundle persistentState, CharSequence description) {
6267        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6268
6269        // Refuse possible leaked file descriptors
6270        if (icicle != null && icicle.hasFileDescriptors()) {
6271            throw new IllegalArgumentException("File descriptors passed in Bundle");
6272        }
6273
6274        final long origId = Binder.clearCallingIdentity();
6275
6276        synchronized (this) {
6277            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6278            if (r != null) {
6279                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6280            }
6281        }
6282
6283        trimApplications();
6284
6285        Binder.restoreCallingIdentity(origId);
6286    }
6287
6288    @Override
6289    public final void activityDestroyed(IBinder token) {
6290        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6291        synchronized (this) {
6292            ActivityStack stack = ActivityRecord.getStackLocked(token);
6293            if (stack != null) {
6294                stack.activityDestroyedLocked(token);
6295            }
6296        }
6297    }
6298
6299    @Override
6300    public final void backgroundResourcesReleased(IBinder token) {
6301        final long origId = Binder.clearCallingIdentity();
6302        try {
6303            synchronized (this) {
6304                ActivityStack stack = ActivityRecord.getStackLocked(token);
6305                if (stack != null) {
6306                    stack.backgroundResourcesReleased(token);
6307                }
6308            }
6309        } finally {
6310            Binder.restoreCallingIdentity(origId);
6311        }
6312    }
6313
6314    @Override
6315    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6316        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6317    }
6318
6319    @Override
6320    public final void notifyEnterAnimationComplete(IBinder token) {
6321        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6322    }
6323
6324    @Override
6325    public String getCallingPackage(IBinder token) {
6326        synchronized (this) {
6327            ActivityRecord r = getCallingRecordLocked(token);
6328            return r != null ? r.info.packageName : null;
6329        }
6330    }
6331
6332    @Override
6333    public ComponentName getCallingActivity(IBinder token) {
6334        synchronized (this) {
6335            ActivityRecord r = getCallingRecordLocked(token);
6336            return r != null ? r.intent.getComponent() : null;
6337        }
6338    }
6339
6340    private ActivityRecord getCallingRecordLocked(IBinder token) {
6341        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6342        if (r == null) {
6343            return null;
6344        }
6345        return r.resultTo;
6346    }
6347
6348    @Override
6349    public ComponentName getActivityClassForToken(IBinder token) {
6350        synchronized(this) {
6351            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6352            if (r == null) {
6353                return null;
6354            }
6355            return r.intent.getComponent();
6356        }
6357    }
6358
6359    @Override
6360    public String getPackageForToken(IBinder token) {
6361        synchronized(this) {
6362            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6363            if (r == null) {
6364                return null;
6365            }
6366            return r.packageName;
6367        }
6368    }
6369
6370    @Override
6371    public IIntentSender getIntentSender(int type,
6372            String packageName, IBinder token, String resultWho,
6373            int requestCode, Intent[] intents, String[] resolvedTypes,
6374            int flags, Bundle options, int userId) {
6375        enforceNotIsolatedCaller("getIntentSender");
6376        // Refuse possible leaked file descriptors
6377        if (intents != null) {
6378            if (intents.length < 1) {
6379                throw new IllegalArgumentException("Intents array length must be >= 1");
6380            }
6381            for (int i=0; i<intents.length; i++) {
6382                Intent intent = intents[i];
6383                if (intent != null) {
6384                    if (intent.hasFileDescriptors()) {
6385                        throw new IllegalArgumentException("File descriptors passed in Intent");
6386                    }
6387                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6388                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6389                        throw new IllegalArgumentException(
6390                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6391                    }
6392                    intents[i] = new Intent(intent);
6393                }
6394            }
6395            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6396                throw new IllegalArgumentException(
6397                        "Intent array length does not match resolvedTypes length");
6398            }
6399        }
6400        if (options != null) {
6401            if (options.hasFileDescriptors()) {
6402                throw new IllegalArgumentException("File descriptors passed in options");
6403            }
6404        }
6405
6406        synchronized(this) {
6407            int callingUid = Binder.getCallingUid();
6408            int origUserId = userId;
6409            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6410                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6411                    ALLOW_NON_FULL, "getIntentSender", null);
6412            if (origUserId == UserHandle.USER_CURRENT) {
6413                // We don't want to evaluate this until the pending intent is
6414                // actually executed.  However, we do want to always do the
6415                // security checking for it above.
6416                userId = UserHandle.USER_CURRENT;
6417            }
6418            try {
6419                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6420                    int uid = AppGlobals.getPackageManager()
6421                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6422                    if (!UserHandle.isSameApp(callingUid, uid)) {
6423                        String msg = "Permission Denial: getIntentSender() from pid="
6424                            + Binder.getCallingPid()
6425                            + ", uid=" + Binder.getCallingUid()
6426                            + ", (need uid=" + uid + ")"
6427                            + " is not allowed to send as package " + packageName;
6428                        Slog.w(TAG, msg);
6429                        throw new SecurityException(msg);
6430                    }
6431                }
6432
6433                return getIntentSenderLocked(type, packageName, callingUid, userId,
6434                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6435
6436            } catch (RemoteException e) {
6437                throw new SecurityException(e);
6438            }
6439        }
6440    }
6441
6442    IIntentSender getIntentSenderLocked(int type, String packageName,
6443            int callingUid, int userId, IBinder token, String resultWho,
6444            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6445            Bundle options) {
6446        if (DEBUG_MU)
6447            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6448        ActivityRecord activity = null;
6449        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6450            activity = ActivityRecord.isInStackLocked(token);
6451            if (activity == null) {
6452                return null;
6453            }
6454            if (activity.finishing) {
6455                return null;
6456            }
6457        }
6458
6459        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6460        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6461        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6462        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6463                |PendingIntent.FLAG_UPDATE_CURRENT);
6464
6465        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6466                type, packageName, activity, resultWho,
6467                requestCode, intents, resolvedTypes, flags, options, userId);
6468        WeakReference<PendingIntentRecord> ref;
6469        ref = mIntentSenderRecords.get(key);
6470        PendingIntentRecord rec = ref != null ? ref.get() : null;
6471        if (rec != null) {
6472            if (!cancelCurrent) {
6473                if (updateCurrent) {
6474                    if (rec.key.requestIntent != null) {
6475                        rec.key.requestIntent.replaceExtras(intents != null ?
6476                                intents[intents.length - 1] : null);
6477                    }
6478                    if (intents != null) {
6479                        intents[intents.length-1] = rec.key.requestIntent;
6480                        rec.key.allIntents = intents;
6481                        rec.key.allResolvedTypes = resolvedTypes;
6482                    } else {
6483                        rec.key.allIntents = null;
6484                        rec.key.allResolvedTypes = null;
6485                    }
6486                }
6487                return rec;
6488            }
6489            rec.canceled = true;
6490            mIntentSenderRecords.remove(key);
6491        }
6492        if (noCreate) {
6493            return rec;
6494        }
6495        rec = new PendingIntentRecord(this, key, callingUid);
6496        mIntentSenderRecords.put(key, rec.ref);
6497        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6498            if (activity.pendingResults == null) {
6499                activity.pendingResults
6500                        = new HashSet<WeakReference<PendingIntentRecord>>();
6501            }
6502            activity.pendingResults.add(rec.ref);
6503        }
6504        return rec;
6505    }
6506
6507    @Override
6508    public void cancelIntentSender(IIntentSender sender) {
6509        if (!(sender instanceof PendingIntentRecord)) {
6510            return;
6511        }
6512        synchronized(this) {
6513            PendingIntentRecord rec = (PendingIntentRecord)sender;
6514            try {
6515                int uid = AppGlobals.getPackageManager()
6516                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6517                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6518                    String msg = "Permission Denial: cancelIntentSender() from pid="
6519                        + Binder.getCallingPid()
6520                        + ", uid=" + Binder.getCallingUid()
6521                        + " is not allowed to cancel packges "
6522                        + rec.key.packageName;
6523                    Slog.w(TAG, msg);
6524                    throw new SecurityException(msg);
6525                }
6526            } catch (RemoteException e) {
6527                throw new SecurityException(e);
6528            }
6529            cancelIntentSenderLocked(rec, true);
6530        }
6531    }
6532
6533    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6534        rec.canceled = true;
6535        mIntentSenderRecords.remove(rec.key);
6536        if (cleanActivity && rec.key.activity != null) {
6537            rec.key.activity.pendingResults.remove(rec.ref);
6538        }
6539    }
6540
6541    @Override
6542    public String getPackageForIntentSender(IIntentSender pendingResult) {
6543        if (!(pendingResult instanceof PendingIntentRecord)) {
6544            return null;
6545        }
6546        try {
6547            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6548            return res.key.packageName;
6549        } catch (ClassCastException e) {
6550        }
6551        return null;
6552    }
6553
6554    @Override
6555    public int getUidForIntentSender(IIntentSender sender) {
6556        if (sender instanceof PendingIntentRecord) {
6557            try {
6558                PendingIntentRecord res = (PendingIntentRecord)sender;
6559                return res.uid;
6560            } catch (ClassCastException e) {
6561            }
6562        }
6563        return -1;
6564    }
6565
6566    @Override
6567    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6568        if (!(pendingResult instanceof PendingIntentRecord)) {
6569            return false;
6570        }
6571        try {
6572            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6573            if (res.key.allIntents == null) {
6574                return false;
6575            }
6576            for (int i=0; i<res.key.allIntents.length; i++) {
6577                Intent intent = res.key.allIntents[i];
6578                if (intent.getPackage() != null && intent.getComponent() != null) {
6579                    return false;
6580                }
6581            }
6582            return true;
6583        } catch (ClassCastException e) {
6584        }
6585        return false;
6586    }
6587
6588    @Override
6589    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6590        if (!(pendingResult instanceof PendingIntentRecord)) {
6591            return false;
6592        }
6593        try {
6594            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6595            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6596                return true;
6597            }
6598            return false;
6599        } catch (ClassCastException e) {
6600        }
6601        return false;
6602    }
6603
6604    @Override
6605    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6606        if (!(pendingResult instanceof PendingIntentRecord)) {
6607            return null;
6608        }
6609        try {
6610            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6611            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6612        } catch (ClassCastException e) {
6613        }
6614        return null;
6615    }
6616
6617    @Override
6618    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6619        if (!(pendingResult instanceof PendingIntentRecord)) {
6620            return null;
6621        }
6622        try {
6623            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6624            Intent intent = res.key.requestIntent;
6625            if (intent != null) {
6626                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6627                        || res.lastTagPrefix.equals(prefix))) {
6628                    return res.lastTag;
6629                }
6630                res.lastTagPrefix = prefix;
6631                StringBuilder sb = new StringBuilder(128);
6632                if (prefix != null) {
6633                    sb.append(prefix);
6634                }
6635                if (intent.getAction() != null) {
6636                    sb.append(intent.getAction());
6637                } else if (intent.getComponent() != null) {
6638                    intent.getComponent().appendShortString(sb);
6639                } else {
6640                    sb.append("?");
6641                }
6642                return res.lastTag = sb.toString();
6643            }
6644        } catch (ClassCastException e) {
6645        }
6646        return null;
6647    }
6648
6649    @Override
6650    public void setProcessLimit(int max) {
6651        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6652                "setProcessLimit()");
6653        synchronized (this) {
6654            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6655            mProcessLimitOverride = max;
6656        }
6657        trimApplications();
6658    }
6659
6660    @Override
6661    public int getProcessLimit() {
6662        synchronized (this) {
6663            return mProcessLimitOverride;
6664        }
6665    }
6666
6667    void foregroundTokenDied(ForegroundToken token) {
6668        synchronized (ActivityManagerService.this) {
6669            synchronized (mPidsSelfLocked) {
6670                ForegroundToken cur
6671                    = mForegroundProcesses.get(token.pid);
6672                if (cur != token) {
6673                    return;
6674                }
6675                mForegroundProcesses.remove(token.pid);
6676                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6677                if (pr == null) {
6678                    return;
6679                }
6680                pr.forcingToForeground = null;
6681                updateProcessForegroundLocked(pr, false, false);
6682            }
6683            updateOomAdjLocked();
6684        }
6685    }
6686
6687    @Override
6688    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6689        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6690                "setProcessForeground()");
6691        synchronized(this) {
6692            boolean changed = false;
6693
6694            synchronized (mPidsSelfLocked) {
6695                ProcessRecord pr = mPidsSelfLocked.get(pid);
6696                if (pr == null && isForeground) {
6697                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6698                    return;
6699                }
6700                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6701                if (oldToken != null) {
6702                    oldToken.token.unlinkToDeath(oldToken, 0);
6703                    mForegroundProcesses.remove(pid);
6704                    if (pr != null) {
6705                        pr.forcingToForeground = null;
6706                    }
6707                    changed = true;
6708                }
6709                if (isForeground && token != null) {
6710                    ForegroundToken newToken = new ForegroundToken() {
6711                        @Override
6712                        public void binderDied() {
6713                            foregroundTokenDied(this);
6714                        }
6715                    };
6716                    newToken.pid = pid;
6717                    newToken.token = token;
6718                    try {
6719                        token.linkToDeath(newToken, 0);
6720                        mForegroundProcesses.put(pid, newToken);
6721                        pr.forcingToForeground = token;
6722                        changed = true;
6723                    } catch (RemoteException e) {
6724                        // If the process died while doing this, we will later
6725                        // do the cleanup with the process death link.
6726                    }
6727                }
6728            }
6729
6730            if (changed) {
6731                updateOomAdjLocked();
6732            }
6733        }
6734    }
6735
6736    // =========================================================
6737    // PERMISSIONS
6738    // =========================================================
6739
6740    static class PermissionController extends IPermissionController.Stub {
6741        ActivityManagerService mActivityManagerService;
6742        PermissionController(ActivityManagerService activityManagerService) {
6743            mActivityManagerService = activityManagerService;
6744        }
6745
6746        @Override
6747        public boolean checkPermission(String permission, int pid, int uid) {
6748            return mActivityManagerService.checkPermission(permission, pid,
6749                    uid) == PackageManager.PERMISSION_GRANTED;
6750        }
6751    }
6752
6753    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6754        @Override
6755        public int checkComponentPermission(String permission, int pid, int uid,
6756                int owningUid, boolean exported) {
6757            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6758                    owningUid, exported);
6759        }
6760
6761        @Override
6762        public Object getAMSLock() {
6763            return ActivityManagerService.this;
6764        }
6765    }
6766
6767    /**
6768     * This can be called with or without the global lock held.
6769     */
6770    int checkComponentPermission(String permission, int pid, int uid,
6771            int owningUid, boolean exported) {
6772        // We might be performing an operation on behalf of an indirect binder
6773        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6774        // client identity accordingly before proceeding.
6775        Identity tlsIdentity = sCallerIdentity.get();
6776        if (tlsIdentity != null) {
6777            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6778                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6779            uid = tlsIdentity.uid;
6780            pid = tlsIdentity.pid;
6781        }
6782
6783        if (pid == MY_PID) {
6784            return PackageManager.PERMISSION_GRANTED;
6785        }
6786
6787        return ActivityManager.checkComponentPermission(permission, uid,
6788                owningUid, exported);
6789    }
6790
6791    /**
6792     * As the only public entry point for permissions checking, this method
6793     * can enforce the semantic that requesting a check on a null global
6794     * permission is automatically denied.  (Internally a null permission
6795     * string is used when calling {@link #checkComponentPermission} in cases
6796     * when only uid-based security is needed.)
6797     *
6798     * This can be called with or without the global lock held.
6799     */
6800    @Override
6801    public int checkPermission(String permission, int pid, int uid) {
6802        if (permission == null) {
6803            return PackageManager.PERMISSION_DENIED;
6804        }
6805        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6806    }
6807
6808    /**
6809     * Binder IPC calls go through the public entry point.
6810     * This can be called with or without the global lock held.
6811     */
6812    int checkCallingPermission(String permission) {
6813        return checkPermission(permission,
6814                Binder.getCallingPid(),
6815                UserHandle.getAppId(Binder.getCallingUid()));
6816    }
6817
6818    /**
6819     * This can be called with or without the global lock held.
6820     */
6821    void enforceCallingPermission(String permission, String func) {
6822        if (checkCallingPermission(permission)
6823                == PackageManager.PERMISSION_GRANTED) {
6824            return;
6825        }
6826
6827        String msg = "Permission Denial: " + func + " from pid="
6828                + Binder.getCallingPid()
6829                + ", uid=" + Binder.getCallingUid()
6830                + " requires " + permission;
6831        Slog.w(TAG, msg);
6832        throw new SecurityException(msg);
6833    }
6834
6835    /**
6836     * Determine if UID is holding permissions required to access {@link Uri} in
6837     * the given {@link ProviderInfo}. Final permission checking is always done
6838     * in {@link ContentProvider}.
6839     */
6840    private final boolean checkHoldingPermissionsLocked(
6841            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6842        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6843                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6844        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6845            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6846                    != PERMISSION_GRANTED) {
6847                return false;
6848            }
6849        }
6850        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6851    }
6852
6853    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6854            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6855        if (pi.applicationInfo.uid == uid) {
6856            return true;
6857        } else if (!pi.exported) {
6858            return false;
6859        }
6860
6861        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6862        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6863        try {
6864            // check if target holds top-level <provider> permissions
6865            if (!readMet && pi.readPermission != null && considerUidPermissions
6866                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6867                readMet = true;
6868            }
6869            if (!writeMet && pi.writePermission != null && considerUidPermissions
6870                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6871                writeMet = true;
6872            }
6873
6874            // track if unprotected read/write is allowed; any denied
6875            // <path-permission> below removes this ability
6876            boolean allowDefaultRead = pi.readPermission == null;
6877            boolean allowDefaultWrite = pi.writePermission == null;
6878
6879            // check if target holds any <path-permission> that match uri
6880            final PathPermission[] pps = pi.pathPermissions;
6881            if (pps != null) {
6882                final String path = grantUri.uri.getPath();
6883                int i = pps.length;
6884                while (i > 0 && (!readMet || !writeMet)) {
6885                    i--;
6886                    PathPermission pp = pps[i];
6887                    if (pp.match(path)) {
6888                        if (!readMet) {
6889                            final String pprperm = pp.getReadPermission();
6890                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6891                                    + pprperm + " for " + pp.getPath()
6892                                    + ": match=" + pp.match(path)
6893                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6894                            if (pprperm != null) {
6895                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6896                                        == PERMISSION_GRANTED) {
6897                                    readMet = true;
6898                                } else {
6899                                    allowDefaultRead = false;
6900                                }
6901                            }
6902                        }
6903                        if (!writeMet) {
6904                            final String ppwperm = pp.getWritePermission();
6905                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6906                                    + ppwperm + " for " + pp.getPath()
6907                                    + ": match=" + pp.match(path)
6908                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6909                            if (ppwperm != null) {
6910                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6911                                        == PERMISSION_GRANTED) {
6912                                    writeMet = true;
6913                                } else {
6914                                    allowDefaultWrite = false;
6915                                }
6916                            }
6917                        }
6918                    }
6919                }
6920            }
6921
6922            // grant unprotected <provider> read/write, if not blocked by
6923            // <path-permission> above
6924            if (allowDefaultRead) readMet = true;
6925            if (allowDefaultWrite) writeMet = true;
6926
6927        } catch (RemoteException e) {
6928            return false;
6929        }
6930
6931        return readMet && writeMet;
6932    }
6933
6934    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6935        ProviderInfo pi = null;
6936        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6937        if (cpr != null) {
6938            pi = cpr.info;
6939        } else {
6940            try {
6941                pi = AppGlobals.getPackageManager().resolveContentProvider(
6942                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6943            } catch (RemoteException ex) {
6944            }
6945        }
6946        return pi;
6947    }
6948
6949    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6950        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6951        if (targetUris != null) {
6952            return targetUris.get(grantUri);
6953        }
6954        return null;
6955    }
6956
6957    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6958            String targetPkg, int targetUid, GrantUri grantUri) {
6959        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6960        if (targetUris == null) {
6961            targetUris = Maps.newArrayMap();
6962            mGrantedUriPermissions.put(targetUid, targetUris);
6963        }
6964
6965        UriPermission perm = targetUris.get(grantUri);
6966        if (perm == null) {
6967            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6968            targetUris.put(grantUri, perm);
6969        }
6970
6971        return perm;
6972    }
6973
6974    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6975            final int modeFlags) {
6976        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6977        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6978                : UriPermission.STRENGTH_OWNED;
6979
6980        // Root gets to do everything.
6981        if (uid == 0) {
6982            return true;
6983        }
6984
6985        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6986        if (perms == null) return false;
6987
6988        // First look for exact match
6989        final UriPermission exactPerm = perms.get(grantUri);
6990        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6991            return true;
6992        }
6993
6994        // No exact match, look for prefixes
6995        final int N = perms.size();
6996        for (int i = 0; i < N; i++) {
6997            final UriPermission perm = perms.valueAt(i);
6998            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6999                    && perm.getStrength(modeFlags) >= minStrength) {
7000                return true;
7001            }
7002        }
7003
7004        return false;
7005    }
7006
7007    /**
7008     * @param uri This uri must NOT contain an embedded userId.
7009     * @param userId The userId in which the uri is to be resolved.
7010     */
7011    @Override
7012    public int checkUriPermission(Uri uri, int pid, int uid,
7013            final int modeFlags, int userId) {
7014        enforceNotIsolatedCaller("checkUriPermission");
7015
7016        // Another redirected-binder-call permissions check as in
7017        // {@link checkComponentPermission}.
7018        Identity tlsIdentity = sCallerIdentity.get();
7019        if (tlsIdentity != null) {
7020            uid = tlsIdentity.uid;
7021            pid = tlsIdentity.pid;
7022        }
7023
7024        // Our own process gets to do everything.
7025        if (pid == MY_PID) {
7026            return PackageManager.PERMISSION_GRANTED;
7027        }
7028        synchronized (this) {
7029            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7030                    ? PackageManager.PERMISSION_GRANTED
7031                    : PackageManager.PERMISSION_DENIED;
7032        }
7033    }
7034
7035    /**
7036     * Check if the targetPkg can be granted permission to access uri by
7037     * the callingUid using the given modeFlags.  Throws a security exception
7038     * if callingUid is not allowed to do this.  Returns the uid of the target
7039     * if the URI permission grant should be performed; returns -1 if it is not
7040     * needed (for example targetPkg already has permission to access the URI).
7041     * If you already know the uid of the target, you can supply it in
7042     * lastTargetUid else set that to -1.
7043     */
7044    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7045            final int modeFlags, int lastTargetUid) {
7046        if (!Intent.isAccessUriMode(modeFlags)) {
7047            return -1;
7048        }
7049
7050        if (targetPkg != null) {
7051            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7052                    "Checking grant " + targetPkg + " permission to " + grantUri);
7053        }
7054
7055        final IPackageManager pm = AppGlobals.getPackageManager();
7056
7057        // If this is not a content: uri, we can't do anything with it.
7058        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7059            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7060                    "Can't grant URI permission for non-content URI: " + grantUri);
7061            return -1;
7062        }
7063
7064        final String authority = grantUri.uri.getAuthority();
7065        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7066        if (pi == null) {
7067            Slog.w(TAG, "No content provider found for permission check: " +
7068                    grantUri.uri.toSafeString());
7069            return -1;
7070        }
7071
7072        int targetUid = lastTargetUid;
7073        if (targetUid < 0 && targetPkg != null) {
7074            try {
7075                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7076                if (targetUid < 0) {
7077                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7078                            "Can't grant URI permission no uid for: " + targetPkg);
7079                    return -1;
7080                }
7081            } catch (RemoteException ex) {
7082                return -1;
7083            }
7084        }
7085
7086        if (targetUid >= 0) {
7087            // First...  does the target actually need this permission?
7088            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7089                // No need to grant the target this permission.
7090                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7091                        "Target " + targetPkg + " already has full permission to " + grantUri);
7092                return -1;
7093            }
7094        } else {
7095            // First...  there is no target package, so can anyone access it?
7096            boolean allowed = pi.exported;
7097            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7098                if (pi.readPermission != null) {
7099                    allowed = false;
7100                }
7101            }
7102            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7103                if (pi.writePermission != null) {
7104                    allowed = false;
7105                }
7106            }
7107            if (allowed) {
7108                return -1;
7109            }
7110        }
7111
7112        /* There is a special cross user grant if:
7113         * - The target is on another user.
7114         * - Apps on the current user can access the uri without any uid permissions.
7115         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7116         * grant uri permissions.
7117         */
7118        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7119                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7120                modeFlags, false /*without considering the uid permissions*/);
7121
7122        // Second...  is the provider allowing granting of URI permissions?
7123        if (!specialCrossUserGrant) {
7124            if (!pi.grantUriPermissions) {
7125                throw new SecurityException("Provider " + pi.packageName
7126                        + "/" + pi.name
7127                        + " does not allow granting of Uri permissions (uri "
7128                        + grantUri + ")");
7129            }
7130            if (pi.uriPermissionPatterns != null) {
7131                final int N = pi.uriPermissionPatterns.length;
7132                boolean allowed = false;
7133                for (int i=0; i<N; i++) {
7134                    if (pi.uriPermissionPatterns[i] != null
7135                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7136                        allowed = true;
7137                        break;
7138                    }
7139                }
7140                if (!allowed) {
7141                    throw new SecurityException("Provider " + pi.packageName
7142                            + "/" + pi.name
7143                            + " does not allow granting of permission to path of Uri "
7144                            + grantUri);
7145                }
7146            }
7147        }
7148
7149        // Third...  does the caller itself have permission to access
7150        // this uri?
7151        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7152            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7153                // Require they hold a strong enough Uri permission
7154                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7155                    throw new SecurityException("Uid " + callingUid
7156                            + " does not have permission to uri " + grantUri);
7157                }
7158            }
7159        }
7160        return targetUid;
7161    }
7162
7163    /**
7164     * @param uri This uri must NOT contain an embedded userId.
7165     * @param userId The userId in which the uri is to be resolved.
7166     */
7167    @Override
7168    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7169            final int modeFlags, int userId) {
7170        enforceNotIsolatedCaller("checkGrantUriPermission");
7171        synchronized(this) {
7172            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7173                    new GrantUri(userId, uri, false), modeFlags, -1);
7174        }
7175    }
7176
7177    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7178            final int modeFlags, UriPermissionOwner owner) {
7179        if (!Intent.isAccessUriMode(modeFlags)) {
7180            return;
7181        }
7182
7183        // So here we are: the caller has the assumed permission
7184        // to the uri, and the target doesn't.  Let's now give this to
7185        // the target.
7186
7187        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7188                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7189
7190        final String authority = grantUri.uri.getAuthority();
7191        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7192        if (pi == null) {
7193            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7194            return;
7195        }
7196
7197        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7198            grantUri.prefix = true;
7199        }
7200        final UriPermission perm = findOrCreateUriPermissionLocked(
7201                pi.packageName, targetPkg, targetUid, grantUri);
7202        perm.grantModes(modeFlags, owner);
7203    }
7204
7205    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7206            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7207        if (targetPkg == null) {
7208            throw new NullPointerException("targetPkg");
7209        }
7210        int targetUid;
7211        final IPackageManager pm = AppGlobals.getPackageManager();
7212        try {
7213            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7214        } catch (RemoteException ex) {
7215            return;
7216        }
7217
7218        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7219                targetUid);
7220        if (targetUid < 0) {
7221            return;
7222        }
7223
7224        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7225                owner);
7226    }
7227
7228    static class NeededUriGrants extends ArrayList<GrantUri> {
7229        final String targetPkg;
7230        final int targetUid;
7231        final int flags;
7232
7233        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7234            this.targetPkg = targetPkg;
7235            this.targetUid = targetUid;
7236            this.flags = flags;
7237        }
7238    }
7239
7240    /**
7241     * Like checkGrantUriPermissionLocked, but takes an Intent.
7242     */
7243    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7244            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7245        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7246                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7247                + " clip=" + (intent != null ? intent.getClipData() : null)
7248                + " from " + intent + "; flags=0x"
7249                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7250
7251        if (targetPkg == null) {
7252            throw new NullPointerException("targetPkg");
7253        }
7254
7255        if (intent == null) {
7256            return null;
7257        }
7258        Uri data = intent.getData();
7259        ClipData clip = intent.getClipData();
7260        if (data == null && clip == null) {
7261            return null;
7262        }
7263        // Default userId for uris in the intent (if they don't specify it themselves)
7264        int contentUserHint = intent.getContentUserHint();
7265        if (contentUserHint == UserHandle.USER_CURRENT) {
7266            contentUserHint = UserHandle.getUserId(callingUid);
7267        }
7268        final IPackageManager pm = AppGlobals.getPackageManager();
7269        int targetUid;
7270        if (needed != null) {
7271            targetUid = needed.targetUid;
7272        } else {
7273            try {
7274                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7275            } catch (RemoteException ex) {
7276                return null;
7277            }
7278            if (targetUid < 0) {
7279                if (DEBUG_URI_PERMISSION) {
7280                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7281                            + " on user " + targetUserId);
7282                }
7283                return null;
7284            }
7285        }
7286        if (data != null) {
7287            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7288            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7289                    targetUid);
7290            if (targetUid > 0) {
7291                if (needed == null) {
7292                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7293                }
7294                needed.add(grantUri);
7295            }
7296        }
7297        if (clip != null) {
7298            for (int i=0; i<clip.getItemCount(); i++) {
7299                Uri uri = clip.getItemAt(i).getUri();
7300                if (uri != null) {
7301                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7302                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7303                            targetUid);
7304                    if (targetUid > 0) {
7305                        if (needed == null) {
7306                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7307                        }
7308                        needed.add(grantUri);
7309                    }
7310                } else {
7311                    Intent clipIntent = clip.getItemAt(i).getIntent();
7312                    if (clipIntent != null) {
7313                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7314                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7315                        if (newNeeded != null) {
7316                            needed = newNeeded;
7317                        }
7318                    }
7319                }
7320            }
7321        }
7322
7323        return needed;
7324    }
7325
7326    /**
7327     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7328     */
7329    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7330            UriPermissionOwner owner) {
7331        if (needed != null) {
7332            for (int i=0; i<needed.size(); i++) {
7333                GrantUri grantUri = needed.get(i);
7334                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7335                        grantUri, needed.flags, owner);
7336            }
7337        }
7338    }
7339
7340    void grantUriPermissionFromIntentLocked(int callingUid,
7341            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7342        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7343                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7344        if (needed == null) {
7345            return;
7346        }
7347
7348        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7349    }
7350
7351    /**
7352     * @param uri This uri must NOT contain an embedded userId.
7353     * @param userId The userId in which the uri is to be resolved.
7354     */
7355    @Override
7356    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7357            final int modeFlags, int userId) {
7358        enforceNotIsolatedCaller("grantUriPermission");
7359        GrantUri grantUri = new GrantUri(userId, uri, false);
7360        synchronized(this) {
7361            final ProcessRecord r = getRecordForAppLocked(caller);
7362            if (r == null) {
7363                throw new SecurityException("Unable to find app for caller "
7364                        + caller
7365                        + " when granting permission to uri " + grantUri);
7366            }
7367            if (targetPkg == null) {
7368                throw new IllegalArgumentException("null target");
7369            }
7370            if (grantUri == null) {
7371                throw new IllegalArgumentException("null uri");
7372            }
7373
7374            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7375                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7376                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7377                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7378
7379            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7380                    UserHandle.getUserId(r.uid));
7381        }
7382    }
7383
7384    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7385        if (perm.modeFlags == 0) {
7386            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7387                    perm.targetUid);
7388            if (perms != null) {
7389                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7390                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7391
7392                perms.remove(perm.uri);
7393                if (perms.isEmpty()) {
7394                    mGrantedUriPermissions.remove(perm.targetUid);
7395                }
7396            }
7397        }
7398    }
7399
7400    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7401        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7402
7403        final IPackageManager pm = AppGlobals.getPackageManager();
7404        final String authority = grantUri.uri.getAuthority();
7405        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7406        if (pi == null) {
7407            Slog.w(TAG, "No content provider found for permission revoke: "
7408                    + grantUri.toSafeString());
7409            return;
7410        }
7411
7412        // Does the caller have this permission on the URI?
7413        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7414            // Right now, if you are not the original owner of the permission,
7415            // you are not allowed to revoke it.
7416            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
7417                throw new SecurityException("Uid " + callingUid
7418                        + " does not have permission to uri " + grantUri);
7419            //}
7420        }
7421
7422        boolean persistChanged = false;
7423
7424        // Go through all of the permissions and remove any that match.
7425        int N = mGrantedUriPermissions.size();
7426        for (int i = 0; i < N; i++) {
7427            final int targetUid = mGrantedUriPermissions.keyAt(i);
7428            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7429
7430            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7431                final UriPermission perm = it.next();
7432                if (perm.uri.sourceUserId == grantUri.sourceUserId
7433                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7434                    if (DEBUG_URI_PERMISSION)
7435                        Slog.v(TAG,
7436                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7437                    persistChanged |= perm.revokeModes(
7438                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7439                    if (perm.modeFlags == 0) {
7440                        it.remove();
7441                    }
7442                }
7443            }
7444
7445            if (perms.isEmpty()) {
7446                mGrantedUriPermissions.remove(targetUid);
7447                N--;
7448                i--;
7449            }
7450        }
7451
7452        if (persistChanged) {
7453            schedulePersistUriGrants();
7454        }
7455    }
7456
7457    /**
7458     * @param uri This uri must NOT contain an embedded userId.
7459     * @param userId The userId in which the uri is to be resolved.
7460     */
7461    @Override
7462    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7463            int userId) {
7464        enforceNotIsolatedCaller("revokeUriPermission");
7465        synchronized(this) {
7466            final ProcessRecord r = getRecordForAppLocked(caller);
7467            if (r == null) {
7468                throw new SecurityException("Unable to find app for caller "
7469                        + caller
7470                        + " when revoking permission to uri " + uri);
7471            }
7472            if (uri == null) {
7473                Slog.w(TAG, "revokeUriPermission: null uri");
7474                return;
7475            }
7476
7477            if (!Intent.isAccessUriMode(modeFlags)) {
7478                return;
7479            }
7480
7481            final IPackageManager pm = AppGlobals.getPackageManager();
7482            final String authority = uri.getAuthority();
7483            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7484            if (pi == null) {
7485                Slog.w(TAG, "No content provider found for permission revoke: "
7486                        + uri.toSafeString());
7487                return;
7488            }
7489
7490            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7491        }
7492    }
7493
7494    /**
7495     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7496     * given package.
7497     *
7498     * @param packageName Package name to match, or {@code null} to apply to all
7499     *            packages.
7500     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7501     *            to all users.
7502     * @param persistable If persistable grants should be removed.
7503     */
7504    private void removeUriPermissionsForPackageLocked(
7505            String packageName, int userHandle, boolean persistable) {
7506        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7507            throw new IllegalArgumentException("Must narrow by either package or user");
7508        }
7509
7510        boolean persistChanged = false;
7511
7512        int N = mGrantedUriPermissions.size();
7513        for (int i = 0; i < N; i++) {
7514            final int targetUid = mGrantedUriPermissions.keyAt(i);
7515            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7516
7517            // Only inspect grants matching user
7518            if (userHandle == UserHandle.USER_ALL
7519                    || userHandle == UserHandle.getUserId(targetUid)) {
7520                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7521                    final UriPermission perm = it.next();
7522
7523                    // Only inspect grants matching package
7524                    if (packageName == null || perm.sourcePkg.equals(packageName)
7525                            || perm.targetPkg.equals(packageName)) {
7526                        persistChanged |= perm.revokeModes(
7527                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7528
7529                        // Only remove when no modes remain; any persisted grants
7530                        // will keep this alive.
7531                        if (perm.modeFlags == 0) {
7532                            it.remove();
7533                        }
7534                    }
7535                }
7536
7537                if (perms.isEmpty()) {
7538                    mGrantedUriPermissions.remove(targetUid);
7539                    N--;
7540                    i--;
7541                }
7542            }
7543        }
7544
7545        if (persistChanged) {
7546            schedulePersistUriGrants();
7547        }
7548    }
7549
7550    @Override
7551    public IBinder newUriPermissionOwner(String name) {
7552        enforceNotIsolatedCaller("newUriPermissionOwner");
7553        synchronized(this) {
7554            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7555            return owner.getExternalTokenLocked();
7556        }
7557    }
7558
7559    /**
7560     * @param uri This uri must NOT contain an embedded userId.
7561     * @param sourceUserId The userId in which the uri is to be resolved.
7562     * @param targetUserId The userId of the app that receives the grant.
7563     */
7564    @Override
7565    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7566            final int modeFlags, int sourceUserId, int targetUserId) {
7567        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7568                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7569        synchronized(this) {
7570            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7571            if (owner == null) {
7572                throw new IllegalArgumentException("Unknown owner: " + token);
7573            }
7574            if (fromUid != Binder.getCallingUid()) {
7575                if (Binder.getCallingUid() != Process.myUid()) {
7576                    // Only system code can grant URI permissions on behalf
7577                    // of other users.
7578                    throw new SecurityException("nice try");
7579                }
7580            }
7581            if (targetPkg == null) {
7582                throw new IllegalArgumentException("null target");
7583            }
7584            if (uri == null) {
7585                throw new IllegalArgumentException("null uri");
7586            }
7587
7588            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7589                    modeFlags, owner, targetUserId);
7590        }
7591    }
7592
7593    /**
7594     * @param uri This uri must NOT contain an embedded userId.
7595     * @param userId The userId in which the uri is to be resolved.
7596     */
7597    @Override
7598    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7599        synchronized(this) {
7600            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7601            if (owner == null) {
7602                throw new IllegalArgumentException("Unknown owner: " + token);
7603            }
7604
7605            if (uri == null) {
7606                owner.removeUriPermissionsLocked(mode);
7607            } else {
7608                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7609            }
7610        }
7611    }
7612
7613    private void schedulePersistUriGrants() {
7614        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7615            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7616                    10 * DateUtils.SECOND_IN_MILLIS);
7617        }
7618    }
7619
7620    private void writeGrantedUriPermissions() {
7621        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7622
7623        // Snapshot permissions so we can persist without lock
7624        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7625        synchronized (this) {
7626            final int size = mGrantedUriPermissions.size();
7627            for (int i = 0; i < size; i++) {
7628                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7629                for (UriPermission perm : perms.values()) {
7630                    if (perm.persistedModeFlags != 0) {
7631                        persist.add(perm.snapshot());
7632                    }
7633                }
7634            }
7635        }
7636
7637        FileOutputStream fos = null;
7638        try {
7639            fos = mGrantFile.startWrite();
7640
7641            XmlSerializer out = new FastXmlSerializer();
7642            out.setOutput(fos, "utf-8");
7643            out.startDocument(null, true);
7644            out.startTag(null, TAG_URI_GRANTS);
7645            for (UriPermission.Snapshot perm : persist) {
7646                out.startTag(null, TAG_URI_GRANT);
7647                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7648                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7649                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7650                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7651                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7652                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7653                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7654                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7655                out.endTag(null, TAG_URI_GRANT);
7656            }
7657            out.endTag(null, TAG_URI_GRANTS);
7658            out.endDocument();
7659
7660            mGrantFile.finishWrite(fos);
7661        } catch (IOException e) {
7662            if (fos != null) {
7663                mGrantFile.failWrite(fos);
7664            }
7665        }
7666    }
7667
7668    private void readGrantedUriPermissionsLocked() {
7669        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7670
7671        final long now = System.currentTimeMillis();
7672
7673        FileInputStream fis = null;
7674        try {
7675            fis = mGrantFile.openRead();
7676            final XmlPullParser in = Xml.newPullParser();
7677            in.setInput(fis, null);
7678
7679            int type;
7680            while ((type = in.next()) != END_DOCUMENT) {
7681                final String tag = in.getName();
7682                if (type == START_TAG) {
7683                    if (TAG_URI_GRANT.equals(tag)) {
7684                        final int sourceUserId;
7685                        final int targetUserId;
7686                        final int userHandle = readIntAttribute(in,
7687                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7688                        if (userHandle != UserHandle.USER_NULL) {
7689                            // For backwards compatibility.
7690                            sourceUserId = userHandle;
7691                            targetUserId = userHandle;
7692                        } else {
7693                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7694                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7695                        }
7696                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7697                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7698                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7699                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7700                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7701                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7702
7703                        // Sanity check that provider still belongs to source package
7704                        final ProviderInfo pi = getProviderInfoLocked(
7705                                uri.getAuthority(), sourceUserId);
7706                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7707                            int targetUid = -1;
7708                            try {
7709                                targetUid = AppGlobals.getPackageManager()
7710                                        .getPackageUid(targetPkg, targetUserId);
7711                            } catch (RemoteException e) {
7712                            }
7713                            if (targetUid != -1) {
7714                                final UriPermission perm = findOrCreateUriPermissionLocked(
7715                                        sourcePkg, targetPkg, targetUid,
7716                                        new GrantUri(sourceUserId, uri, prefix));
7717                                perm.initPersistedModes(modeFlags, createdTime);
7718                            }
7719                        } else {
7720                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7721                                    + " but instead found " + pi);
7722                        }
7723                    }
7724                }
7725            }
7726        } catch (FileNotFoundException e) {
7727            // Missing grants is okay
7728        } catch (IOException e) {
7729            Log.wtf(TAG, "Failed reading Uri grants", e);
7730        } catch (XmlPullParserException e) {
7731            Log.wtf(TAG, "Failed reading Uri grants", e);
7732        } finally {
7733            IoUtils.closeQuietly(fis);
7734        }
7735    }
7736
7737    /**
7738     * @param uri This uri must NOT contain an embedded userId.
7739     * @param userId The userId in which the uri is to be resolved.
7740     */
7741    @Override
7742    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7743        enforceNotIsolatedCaller("takePersistableUriPermission");
7744
7745        Preconditions.checkFlagsArgument(modeFlags,
7746                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7747
7748        synchronized (this) {
7749            final int callingUid = Binder.getCallingUid();
7750            boolean persistChanged = false;
7751            GrantUri grantUri = new GrantUri(userId, uri, false);
7752
7753            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7754                    new GrantUri(userId, uri, false));
7755            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7756                    new GrantUri(userId, uri, true));
7757
7758            final boolean exactValid = (exactPerm != null)
7759                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7760            final boolean prefixValid = (prefixPerm != null)
7761                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7762
7763            if (!(exactValid || prefixValid)) {
7764                throw new SecurityException("No persistable permission grants found for UID "
7765                        + callingUid + " and Uri " + grantUri.toSafeString());
7766            }
7767
7768            if (exactValid) {
7769                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7770            }
7771            if (prefixValid) {
7772                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7773            }
7774
7775            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7776
7777            if (persistChanged) {
7778                schedulePersistUriGrants();
7779            }
7780        }
7781    }
7782
7783    /**
7784     * @param uri This uri must NOT contain an embedded userId.
7785     * @param userId The userId in which the uri is to be resolved.
7786     */
7787    @Override
7788    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7789        enforceNotIsolatedCaller("releasePersistableUriPermission");
7790
7791        Preconditions.checkFlagsArgument(modeFlags,
7792                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7793
7794        synchronized (this) {
7795            final int callingUid = Binder.getCallingUid();
7796            boolean persistChanged = false;
7797
7798            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7799                    new GrantUri(userId, uri, false));
7800            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7801                    new GrantUri(userId, uri, true));
7802            if (exactPerm == null && prefixPerm == null) {
7803                throw new SecurityException("No permission grants found for UID " + callingUid
7804                        + " and Uri " + uri.toSafeString());
7805            }
7806
7807            if (exactPerm != null) {
7808                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7809                removeUriPermissionIfNeededLocked(exactPerm);
7810            }
7811            if (prefixPerm != null) {
7812                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7813                removeUriPermissionIfNeededLocked(prefixPerm);
7814            }
7815
7816            if (persistChanged) {
7817                schedulePersistUriGrants();
7818            }
7819        }
7820    }
7821
7822    /**
7823     * Prune any older {@link UriPermission} for the given UID until outstanding
7824     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7825     *
7826     * @return if any mutations occured that require persisting.
7827     */
7828    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7829        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7830        if (perms == null) return false;
7831        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7832
7833        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7834        for (UriPermission perm : perms.values()) {
7835            if (perm.persistedModeFlags != 0) {
7836                persisted.add(perm);
7837            }
7838        }
7839
7840        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7841        if (trimCount <= 0) return false;
7842
7843        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7844        for (int i = 0; i < trimCount; i++) {
7845            final UriPermission perm = persisted.get(i);
7846
7847            if (DEBUG_URI_PERMISSION) {
7848                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7849            }
7850
7851            perm.releasePersistableModes(~0);
7852            removeUriPermissionIfNeededLocked(perm);
7853        }
7854
7855        return true;
7856    }
7857
7858    @Override
7859    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7860            String packageName, boolean incoming) {
7861        enforceNotIsolatedCaller("getPersistedUriPermissions");
7862        Preconditions.checkNotNull(packageName, "packageName");
7863
7864        final int callingUid = Binder.getCallingUid();
7865        final IPackageManager pm = AppGlobals.getPackageManager();
7866        try {
7867            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7868            if (packageUid != callingUid) {
7869                throw new SecurityException(
7870                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7871            }
7872        } catch (RemoteException e) {
7873            throw new SecurityException("Failed to verify package name ownership");
7874        }
7875
7876        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7877        synchronized (this) {
7878            if (incoming) {
7879                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7880                        callingUid);
7881                if (perms == null) {
7882                    Slog.w(TAG, "No permission grants found for " + packageName);
7883                } else {
7884                    for (UriPermission perm : perms.values()) {
7885                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7886                            result.add(perm.buildPersistedPublicApiObject());
7887                        }
7888                    }
7889                }
7890            } else {
7891                final int size = mGrantedUriPermissions.size();
7892                for (int i = 0; i < size; i++) {
7893                    final ArrayMap<GrantUri, UriPermission> perms =
7894                            mGrantedUriPermissions.valueAt(i);
7895                    for (UriPermission perm : perms.values()) {
7896                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7897                            result.add(perm.buildPersistedPublicApiObject());
7898                        }
7899                    }
7900                }
7901            }
7902        }
7903        return new ParceledListSlice<android.content.UriPermission>(result);
7904    }
7905
7906    @Override
7907    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7908        synchronized (this) {
7909            ProcessRecord app =
7910                who != null ? getRecordForAppLocked(who) : null;
7911            if (app == null) return;
7912
7913            Message msg = Message.obtain();
7914            msg.what = WAIT_FOR_DEBUGGER_MSG;
7915            msg.obj = app;
7916            msg.arg1 = waiting ? 1 : 0;
7917            mHandler.sendMessage(msg);
7918        }
7919    }
7920
7921    @Override
7922    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7923        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7924        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7925        outInfo.availMem = Process.getFreeMemory();
7926        outInfo.totalMem = Process.getTotalMemory();
7927        outInfo.threshold = homeAppMem;
7928        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7929        outInfo.hiddenAppThreshold = cachedAppMem;
7930        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7931                ProcessList.SERVICE_ADJ);
7932        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7933                ProcessList.VISIBLE_APP_ADJ);
7934        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7935                ProcessList.FOREGROUND_APP_ADJ);
7936    }
7937
7938    // =========================================================
7939    // TASK MANAGEMENT
7940    // =========================================================
7941
7942    @Override
7943    public List<IAppTask> getAppTasks(String callingPackage) {
7944        int callingUid = Binder.getCallingUid();
7945        long ident = Binder.clearCallingIdentity();
7946
7947        synchronized(this) {
7948            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7949            try {
7950                if (localLOGV) Slog.v(TAG, "getAppTasks");
7951
7952                final int N = mRecentTasks.size();
7953                for (int i = 0; i < N; i++) {
7954                    TaskRecord tr = mRecentTasks.get(i);
7955                    // Skip tasks that do not match the caller.  We don't need to verify
7956                    // callingPackage, because we are also limiting to callingUid and know
7957                    // that will limit to the correct security sandbox.
7958                    if (tr.effectiveUid != callingUid) {
7959                        continue;
7960                    }
7961                    Intent intent = tr.getBaseIntent();
7962                    if (intent == null ||
7963                            !callingPackage.equals(intent.getComponent().getPackageName())) {
7964                        continue;
7965                    }
7966                    ActivityManager.RecentTaskInfo taskInfo =
7967                            createRecentTaskInfoFromTaskRecord(tr);
7968                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7969                    list.add(taskImpl);
7970                }
7971            } finally {
7972                Binder.restoreCallingIdentity(ident);
7973            }
7974            return list;
7975        }
7976    }
7977
7978    @Override
7979    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7980        final int callingUid = Binder.getCallingUid();
7981        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7982
7983        synchronized(this) {
7984            if (localLOGV) Slog.v(
7985                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7986
7987            final boolean allowed = checkCallingPermission(
7988                    android.Manifest.permission.GET_TASKS)
7989                    == PackageManager.PERMISSION_GRANTED;
7990            if (!allowed) {
7991                Slog.w(TAG, "getTasks: caller " + callingUid
7992                        + " does not hold GET_TASKS; limiting output");
7993            }
7994
7995            // TODO: Improve with MRU list from all ActivityStacks.
7996            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7997        }
7998
7999        return list;
8000    }
8001
8002    TaskRecord getMostRecentTask() {
8003        return mRecentTasks.get(0);
8004    }
8005
8006    /**
8007     * Creates a new RecentTaskInfo from a TaskRecord.
8008     */
8009    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8010        // Update the task description to reflect any changes in the task stack
8011        tr.updateTaskDescription();
8012
8013        // Compose the recent task info
8014        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8015        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8016        rti.persistentId = tr.taskId;
8017        rti.baseIntent = new Intent(tr.getBaseIntent());
8018        rti.origActivity = tr.origActivity;
8019        rti.description = tr.lastDescription;
8020        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8021        rti.userId = tr.userId;
8022        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8023        rti.firstActiveTime = tr.firstActiveTime;
8024        rti.lastActiveTime = tr.lastActiveTime;
8025        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8026        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8027        return rti;
8028    }
8029
8030    @Override
8031    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8032        final int callingUid = Binder.getCallingUid();
8033        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8034                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8035
8036        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8037        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8038        synchronized (this) {
8039            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
8040                    == PackageManager.PERMISSION_GRANTED;
8041            if (!allowed) {
8042                Slog.w(TAG, "getRecentTasks: caller " + callingUid
8043                        + " does not hold GET_TASKS; limiting output");
8044            }
8045            final boolean detailed = checkCallingPermission(
8046                    android.Manifest.permission.GET_DETAILED_TASKS)
8047                    == PackageManager.PERMISSION_GRANTED;
8048
8049            final int N = mRecentTasks.size();
8050            ArrayList<ActivityManager.RecentTaskInfo> res
8051                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8052                            maxNum < N ? maxNum : N);
8053
8054            final Set<Integer> includedUsers;
8055            if (includeProfiles) {
8056                includedUsers = getProfileIdsLocked(userId);
8057            } else {
8058                includedUsers = new HashSet<Integer>();
8059            }
8060            includedUsers.add(Integer.valueOf(userId));
8061
8062            for (int i=0; i<N && maxNum > 0; i++) {
8063                TaskRecord tr = mRecentTasks.get(i);
8064                // Only add calling user or related users recent tasks
8065                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8066                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8067                    continue;
8068                }
8069
8070                // Return the entry if desired by the caller.  We always return
8071                // the first entry, because callers always expect this to be the
8072                // foreground app.  We may filter others if the caller has
8073                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8074                // we should exclude the entry.
8075
8076                if (i == 0
8077                        || withExcluded
8078                        || (tr.intent == null)
8079                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8080                                == 0)) {
8081                    if (!allowed) {
8082                        // If the caller doesn't have the GET_TASKS permission, then only
8083                        // allow them to see a small subset of tasks -- their own and home.
8084                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8085                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8086                            continue;
8087                        }
8088                    }
8089                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8090                        if (tr.stack != null && tr.stack.isHomeStack()) {
8091                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8092                            continue;
8093                        }
8094                    }
8095                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8096                        // Don't include auto remove tasks that are finished or finishing.
8097                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8098                                + tr);
8099                        continue;
8100                    }
8101                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8102                            && !tr.isAvailable) {
8103                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8104                        continue;
8105                    }
8106
8107                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8108                    if (!detailed) {
8109                        rti.baseIntent.replaceExtras((Bundle)null);
8110                    }
8111
8112                    res.add(rti);
8113                    maxNum--;
8114                }
8115            }
8116            return res;
8117        }
8118    }
8119
8120    private TaskRecord recentTaskForIdLocked(int id) {
8121        final int N = mRecentTasks.size();
8122            for (int i=0; i<N; i++) {
8123                TaskRecord tr = mRecentTasks.get(i);
8124                if (tr.taskId == id) {
8125                    return tr;
8126                }
8127            }
8128            return null;
8129    }
8130
8131    @Override
8132    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8133        synchronized (this) {
8134            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8135                    "getTaskThumbnail()");
8136            TaskRecord tr = recentTaskForIdLocked(id);
8137            if (tr != null) {
8138                return tr.getTaskThumbnailLocked();
8139            }
8140        }
8141        return null;
8142    }
8143
8144    @Override
8145    public int addAppTask(IBinder activityToken, Intent intent,
8146            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8147        final int callingUid = Binder.getCallingUid();
8148        final long callingIdent = Binder.clearCallingIdentity();
8149
8150        try {
8151            synchronized (this) {
8152                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8153                if (r == null) {
8154                    throw new IllegalArgumentException("Activity does not exist; token="
8155                            + activityToken);
8156                }
8157                ComponentName comp = intent.getComponent();
8158                if (comp == null) {
8159                    throw new IllegalArgumentException("Intent " + intent
8160                            + " must specify explicit component");
8161                }
8162                if (thumbnail.getWidth() != mThumbnailWidth
8163                        || thumbnail.getHeight() != mThumbnailHeight) {
8164                    throw new IllegalArgumentException("Bad thumbnail size: got "
8165                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8166                            + mThumbnailWidth + "x" + mThumbnailHeight);
8167                }
8168                if (intent.getSelector() != null) {
8169                    intent.setSelector(null);
8170                }
8171                if (intent.getSourceBounds() != null) {
8172                    intent.setSourceBounds(null);
8173                }
8174                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8175                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8176                        // The caller has added this as an auto-remove task...  that makes no
8177                        // sense, so turn off auto-remove.
8178                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8179                    }
8180                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8181                    // Must be a new task.
8182                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8183                }
8184                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8185                    mLastAddedTaskActivity = null;
8186                }
8187                ActivityInfo ainfo = mLastAddedTaskActivity;
8188                if (ainfo == null) {
8189                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8190                            comp, 0, UserHandle.getUserId(callingUid));
8191                    if (ainfo.applicationInfo.uid != callingUid) {
8192                        throw new SecurityException(
8193                                "Can't add task for another application: target uid="
8194                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8195                    }
8196                }
8197
8198                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8199                        intent, description);
8200
8201                int trimIdx = trimRecentsForTask(task, false);
8202                if (trimIdx >= 0) {
8203                    // If this would have caused a trim, then we'll abort because that
8204                    // means it would be added at the end of the list but then just removed.
8205                    return -1;
8206                }
8207
8208                final int N = mRecentTasks.size();
8209                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8210                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8211                    tr.removedFromRecents(mTaskPersister);
8212                }
8213
8214                task.inRecents = true;
8215                mRecentTasks.add(task);
8216                r.task.stack.addTask(task, false, false);
8217
8218                task.setLastThumbnail(thumbnail);
8219                task.freeLastThumbnail();
8220
8221                return task.taskId;
8222            }
8223        } finally {
8224            Binder.restoreCallingIdentity(callingIdent);
8225        }
8226    }
8227
8228    @Override
8229    public Point getAppTaskThumbnailSize() {
8230        synchronized (this) {
8231            return new Point(mThumbnailWidth,  mThumbnailHeight);
8232        }
8233    }
8234
8235    @Override
8236    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8237        synchronized (this) {
8238            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8239            if (r != null) {
8240                r.taskDescription = td;
8241                r.task.updateTaskDescription();
8242            }
8243        }
8244    }
8245
8246    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
8247        mRecentTasks.remove(tr);
8248        tr.removedFromRecents(mTaskPersister);
8249        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
8250        Intent baseIntent = new Intent(
8251                tr.intent != null ? tr.intent : tr.affinityIntent);
8252        ComponentName component = baseIntent.getComponent();
8253        if (component == null) {
8254            Slog.w(TAG, "Now component for base intent of task: " + tr);
8255            return;
8256        }
8257
8258        // Find any running services associated with this app.
8259        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
8260
8261        if (killProcesses) {
8262            // Find any running processes associated with this app.
8263            final String pkg = component.getPackageName();
8264            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
8265            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8266            for (int i=0; i<pmap.size(); i++) {
8267                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8268                for (int j=0; j<uids.size(); j++) {
8269                    ProcessRecord proc = uids.valueAt(j);
8270                    if (proc.userId != tr.userId) {
8271                        continue;
8272                    }
8273                    if (!proc.pkgList.containsKey(pkg)) {
8274                        continue;
8275                    }
8276                    procs.add(proc);
8277                }
8278            }
8279
8280            // Kill the running processes.
8281            for (int i=0; i<procs.size(); i++) {
8282                ProcessRecord pr = procs.get(i);
8283                if (pr == mHomeProcess) {
8284                    // Don't kill the home process along with tasks from the same package.
8285                    continue;
8286                }
8287                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8288                    pr.kill("remove task", true);
8289                } else {
8290                    pr.waitingToKill = "remove task";
8291                }
8292            }
8293        }
8294    }
8295
8296    /**
8297     * Removes the task with the specified task id.
8298     *
8299     * @param taskId Identifier of the task to be removed.
8300     * @param flags Additional operational flags.  May be 0 or
8301     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
8302     * @return Returns true if the given task was found and removed.
8303     */
8304    private boolean removeTaskByIdLocked(int taskId, int flags) {
8305        TaskRecord tr = recentTaskForIdLocked(taskId);
8306        if (tr != null) {
8307            tr.removeTaskActivitiesLocked();
8308            cleanUpRemovedTaskLocked(tr, flags);
8309            if (tr.isPersistable) {
8310                notifyTaskPersisterLocked(null, true);
8311            }
8312            return true;
8313        }
8314        return false;
8315    }
8316
8317    @Override
8318    public boolean removeTask(int taskId, int flags) {
8319        synchronized (this) {
8320            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8321                    "removeTask()");
8322            long ident = Binder.clearCallingIdentity();
8323            try {
8324                return removeTaskByIdLocked(taskId, flags);
8325            } finally {
8326                Binder.restoreCallingIdentity(ident);
8327            }
8328        }
8329    }
8330
8331    /**
8332     * TODO: Add mController hook
8333     */
8334    @Override
8335    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8336        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8337                "moveTaskToFront()");
8338
8339        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8340        synchronized(this) {
8341            moveTaskToFrontLocked(taskId, flags, options);
8342        }
8343    }
8344
8345    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8346        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8347                Binder.getCallingUid(), "Task to front")) {
8348            ActivityOptions.abort(options);
8349            return;
8350        }
8351        final long origId = Binder.clearCallingIdentity();
8352        try {
8353            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8354            if (task == null) {
8355                return;
8356            }
8357            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8358                mStackSupervisor.showLockTaskToast();
8359                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8360                return;
8361            }
8362            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8363            if (prev != null && prev.isRecentsActivity()) {
8364                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8365            }
8366            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8367        } finally {
8368            Binder.restoreCallingIdentity(origId);
8369        }
8370        ActivityOptions.abort(options);
8371    }
8372
8373    @Override
8374    public void moveTaskToBack(int taskId) {
8375        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8376                "moveTaskToBack()");
8377
8378        synchronized(this) {
8379            TaskRecord tr = recentTaskForIdLocked(taskId);
8380            if (tr != null) {
8381                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8382                ActivityStack stack = tr.stack;
8383                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8384                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8385                            Binder.getCallingUid(), "Task to back")) {
8386                        return;
8387                    }
8388                }
8389                final long origId = Binder.clearCallingIdentity();
8390                try {
8391                    stack.moveTaskToBackLocked(taskId, null);
8392                } finally {
8393                    Binder.restoreCallingIdentity(origId);
8394                }
8395            }
8396        }
8397    }
8398
8399    /**
8400     * Moves an activity, and all of the other activities within the same task, to the bottom
8401     * of the history stack.  The activity's order within the task is unchanged.
8402     *
8403     * @param token A reference to the activity we wish to move
8404     * @param nonRoot If false then this only works if the activity is the root
8405     *                of a task; if true it will work for any activity in a task.
8406     * @return Returns true if the move completed, false if not.
8407     */
8408    @Override
8409    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8410        enforceNotIsolatedCaller("moveActivityTaskToBack");
8411        synchronized(this) {
8412            final long origId = Binder.clearCallingIdentity();
8413            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8414            if (taskId >= 0) {
8415                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8416            }
8417            Binder.restoreCallingIdentity(origId);
8418        }
8419        return false;
8420    }
8421
8422    @Override
8423    public void moveTaskBackwards(int task) {
8424        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8425                "moveTaskBackwards()");
8426
8427        synchronized(this) {
8428            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8429                    Binder.getCallingUid(), "Task backwards")) {
8430                return;
8431            }
8432            final long origId = Binder.clearCallingIdentity();
8433            moveTaskBackwardsLocked(task);
8434            Binder.restoreCallingIdentity(origId);
8435        }
8436    }
8437
8438    private final void moveTaskBackwardsLocked(int task) {
8439        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8440    }
8441
8442    @Override
8443    public IBinder getHomeActivityToken() throws RemoteException {
8444        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8445                "getHomeActivityToken()");
8446        synchronized (this) {
8447            return mStackSupervisor.getHomeActivityToken();
8448        }
8449    }
8450
8451    @Override
8452    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8453            IActivityContainerCallback callback) throws RemoteException {
8454        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8455                "createActivityContainer()");
8456        synchronized (this) {
8457            if (parentActivityToken == null) {
8458                throw new IllegalArgumentException("parent token must not be null");
8459            }
8460            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8461            if (r == null) {
8462                return null;
8463            }
8464            if (callback == null) {
8465                throw new IllegalArgumentException("callback must not be null");
8466            }
8467            return mStackSupervisor.createActivityContainer(r, callback);
8468        }
8469    }
8470
8471    @Override
8472    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8473        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8474                "deleteActivityContainer()");
8475        synchronized (this) {
8476            mStackSupervisor.deleteActivityContainer(container);
8477        }
8478    }
8479
8480    @Override
8481    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8482            throws RemoteException {
8483        synchronized (this) {
8484            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8485            if (stack != null) {
8486                return stack.mActivityContainer;
8487            }
8488            return null;
8489        }
8490    }
8491
8492    @Override
8493    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8494        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8495                "moveTaskToStack()");
8496        if (stackId == HOME_STACK_ID) {
8497            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8498                    new RuntimeException("here").fillInStackTrace());
8499        }
8500        synchronized (this) {
8501            long ident = Binder.clearCallingIdentity();
8502            try {
8503                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8504                        + stackId + " toTop=" + toTop);
8505                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8506            } finally {
8507                Binder.restoreCallingIdentity(ident);
8508            }
8509        }
8510    }
8511
8512    @Override
8513    public void resizeStack(int stackBoxId, Rect bounds) {
8514        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8515                "resizeStackBox()");
8516        long ident = Binder.clearCallingIdentity();
8517        try {
8518            mWindowManager.resizeStack(stackBoxId, bounds);
8519        } finally {
8520            Binder.restoreCallingIdentity(ident);
8521        }
8522    }
8523
8524    @Override
8525    public List<StackInfo> getAllStackInfos() {
8526        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8527                "getAllStackInfos()");
8528        long ident = Binder.clearCallingIdentity();
8529        try {
8530            synchronized (this) {
8531                return mStackSupervisor.getAllStackInfosLocked();
8532            }
8533        } finally {
8534            Binder.restoreCallingIdentity(ident);
8535        }
8536    }
8537
8538    @Override
8539    public StackInfo getStackInfo(int stackId) {
8540        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8541                "getStackInfo()");
8542        long ident = Binder.clearCallingIdentity();
8543        try {
8544            synchronized (this) {
8545                return mStackSupervisor.getStackInfoLocked(stackId);
8546            }
8547        } finally {
8548            Binder.restoreCallingIdentity(ident);
8549        }
8550    }
8551
8552    @Override
8553    public boolean isInHomeStack(int taskId) {
8554        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8555                "getStackInfo()");
8556        long ident = Binder.clearCallingIdentity();
8557        try {
8558            synchronized (this) {
8559                TaskRecord tr = recentTaskForIdLocked(taskId);
8560                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8561            }
8562        } finally {
8563            Binder.restoreCallingIdentity(ident);
8564        }
8565    }
8566
8567    @Override
8568    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8569        synchronized(this) {
8570            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8571        }
8572    }
8573
8574    private boolean isLockTaskAuthorized(String pkg) {
8575        final DevicePolicyManager dpm = (DevicePolicyManager)
8576                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8577        try {
8578            int uid = mContext.getPackageManager().getPackageUid(pkg,
8579                    Binder.getCallingUserHandle().getIdentifier());
8580            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8581        } catch (NameNotFoundException e) {
8582            return false;
8583        }
8584    }
8585
8586    void startLockTaskMode(TaskRecord task) {
8587        final String pkg;
8588        synchronized (this) {
8589            pkg = task.intent.getComponent().getPackageName();
8590        }
8591        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8592        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8593            final TaskRecord taskRecord = task;
8594            mHandler.post(new Runnable() {
8595                @Override
8596                public void run() {
8597                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8598                }
8599            });
8600            return;
8601        }
8602        long ident = Binder.clearCallingIdentity();
8603        try {
8604            synchronized (this) {
8605                // Since we lost lock on task, make sure it is still there.
8606                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8607                if (task != null) {
8608                    if (!isSystemInitiated
8609                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8610                        throw new IllegalArgumentException("Invalid task, not in foreground");
8611                    }
8612                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8613                }
8614            }
8615        } finally {
8616            Binder.restoreCallingIdentity(ident);
8617        }
8618    }
8619
8620    @Override
8621    public void startLockTaskMode(int taskId) {
8622        final TaskRecord task;
8623        long ident = Binder.clearCallingIdentity();
8624        try {
8625            synchronized (this) {
8626                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8627            }
8628        } finally {
8629            Binder.restoreCallingIdentity(ident);
8630        }
8631        if (task != null) {
8632            startLockTaskMode(task);
8633        }
8634    }
8635
8636    @Override
8637    public void startLockTaskMode(IBinder token) {
8638        final TaskRecord task;
8639        long ident = Binder.clearCallingIdentity();
8640        try {
8641            synchronized (this) {
8642                final ActivityRecord r = ActivityRecord.forToken(token);
8643                if (r == null) {
8644                    return;
8645                }
8646                task = r.task;
8647            }
8648        } finally {
8649            Binder.restoreCallingIdentity(ident);
8650        }
8651        if (task != null) {
8652            startLockTaskMode(task);
8653        }
8654    }
8655
8656    @Override
8657    public void startLockTaskModeOnCurrent() throws RemoteException {
8658        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8659        ActivityRecord r = null;
8660        synchronized (this) {
8661            r = mStackSupervisor.topRunningActivityLocked();
8662        }
8663        startLockTaskMode(r.task);
8664    }
8665
8666    @Override
8667    public void stopLockTaskMode() {
8668        // Verify that the user matches the package of the intent for the TaskRecord
8669        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8670        // and stopLockTaskMode.
8671        final int callingUid = Binder.getCallingUid();
8672        if (callingUid != Process.SYSTEM_UID) {
8673            try {
8674                String pkg =
8675                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8676                int uid = mContext.getPackageManager().getPackageUid(pkg,
8677                        Binder.getCallingUserHandle().getIdentifier());
8678                if (uid != callingUid) {
8679                    throw new SecurityException("Invalid uid, expected " + uid);
8680                }
8681            } catch (NameNotFoundException e) {
8682                Log.d(TAG, "stopLockTaskMode " + e);
8683                return;
8684            }
8685        }
8686        long ident = Binder.clearCallingIdentity();
8687        try {
8688            Log.d(TAG, "stopLockTaskMode");
8689            // Stop lock task
8690            synchronized (this) {
8691                mStackSupervisor.setLockTaskModeLocked(null, false);
8692            }
8693        } finally {
8694            Binder.restoreCallingIdentity(ident);
8695        }
8696    }
8697
8698    @Override
8699    public void stopLockTaskModeOnCurrent() throws RemoteException {
8700        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8701        long ident = Binder.clearCallingIdentity();
8702        try {
8703            stopLockTaskMode();
8704        } finally {
8705            Binder.restoreCallingIdentity(ident);
8706        }
8707    }
8708
8709    @Override
8710    public boolean isInLockTaskMode() {
8711        synchronized (this) {
8712            return mStackSupervisor.isInLockTaskMode();
8713        }
8714    }
8715
8716    // =========================================================
8717    // CONTENT PROVIDERS
8718    // =========================================================
8719
8720    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8721        List<ProviderInfo> providers = null;
8722        try {
8723            providers = AppGlobals.getPackageManager().
8724                queryContentProviders(app.processName, app.uid,
8725                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8726        } catch (RemoteException ex) {
8727        }
8728        if (DEBUG_MU)
8729            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8730        int userId = app.userId;
8731        if (providers != null) {
8732            int N = providers.size();
8733            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8734            for (int i=0; i<N; i++) {
8735                ProviderInfo cpi =
8736                    (ProviderInfo)providers.get(i);
8737                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8738                        cpi.name, cpi.flags);
8739                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8740                    // This is a singleton provider, but a user besides the
8741                    // default user is asking to initialize a process it runs
8742                    // in...  well, no, it doesn't actually run in this process,
8743                    // it runs in the process of the default user.  Get rid of it.
8744                    providers.remove(i);
8745                    N--;
8746                    i--;
8747                    continue;
8748                }
8749
8750                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8751                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8752                if (cpr == null) {
8753                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8754                    mProviderMap.putProviderByClass(comp, cpr);
8755                }
8756                if (DEBUG_MU)
8757                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8758                app.pubProviders.put(cpi.name, cpr);
8759                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8760                    // Don't add this if it is a platform component that is marked
8761                    // to run in multiple processes, because this is actually
8762                    // part of the framework so doesn't make sense to track as a
8763                    // separate apk in the process.
8764                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8765                            mProcessStats);
8766                }
8767                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8768            }
8769        }
8770        return providers;
8771    }
8772
8773    /**
8774     * Check if {@link ProcessRecord} has a possible chance at accessing the
8775     * given {@link ProviderInfo}. Final permission checking is always done
8776     * in {@link ContentProvider}.
8777     */
8778    private final String checkContentProviderPermissionLocked(
8779            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8780        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8781        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8782        boolean checkedGrants = false;
8783        if (checkUser) {
8784            // Looking for cross-user grants before enforcing the typical cross-users permissions
8785            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8786            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8787                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8788                    return null;
8789                }
8790                checkedGrants = true;
8791            }
8792            userId = handleIncomingUser(callingPid, callingUid, userId,
8793                    false, ALLOW_NON_FULL,
8794                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8795            if (userId != tmpTargetUserId) {
8796                // When we actually went to determine the final targer user ID, this ended
8797                // up different than our initial check for the authority.  This is because
8798                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8799                // SELF.  So we need to re-check the grants again.
8800                checkedGrants = false;
8801            }
8802        }
8803        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8804                cpi.applicationInfo.uid, cpi.exported)
8805                == PackageManager.PERMISSION_GRANTED) {
8806            return null;
8807        }
8808        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8809                cpi.applicationInfo.uid, cpi.exported)
8810                == PackageManager.PERMISSION_GRANTED) {
8811            return null;
8812        }
8813
8814        PathPermission[] pps = cpi.pathPermissions;
8815        if (pps != null) {
8816            int i = pps.length;
8817            while (i > 0) {
8818                i--;
8819                PathPermission pp = pps[i];
8820                String pprperm = pp.getReadPermission();
8821                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8822                        cpi.applicationInfo.uid, cpi.exported)
8823                        == PackageManager.PERMISSION_GRANTED) {
8824                    return null;
8825                }
8826                String ppwperm = pp.getWritePermission();
8827                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8828                        cpi.applicationInfo.uid, cpi.exported)
8829                        == PackageManager.PERMISSION_GRANTED) {
8830                    return null;
8831                }
8832            }
8833        }
8834        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8835            return null;
8836        }
8837
8838        String msg;
8839        if (!cpi.exported) {
8840            msg = "Permission Denial: opening provider " + cpi.name
8841                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8842                    + ", uid=" + callingUid + ") that is not exported from uid "
8843                    + cpi.applicationInfo.uid;
8844        } else {
8845            msg = "Permission Denial: opening provider " + cpi.name
8846                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8847                    + ", uid=" + callingUid + ") requires "
8848                    + cpi.readPermission + " or " + cpi.writePermission;
8849        }
8850        Slog.w(TAG, msg);
8851        return msg;
8852    }
8853
8854    /**
8855     * Returns if the ContentProvider has granted a uri to callingUid
8856     */
8857    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8858        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8859        if (perms != null) {
8860            for (int i=perms.size()-1; i>=0; i--) {
8861                GrantUri grantUri = perms.keyAt(i);
8862                if (grantUri.sourceUserId == userId || !checkUser) {
8863                    if (matchesProvider(grantUri.uri, cpi)) {
8864                        return true;
8865                    }
8866                }
8867            }
8868        }
8869        return false;
8870    }
8871
8872    /**
8873     * Returns true if the uri authority is one of the authorities specified in the provider.
8874     */
8875    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8876        String uriAuth = uri.getAuthority();
8877        String cpiAuth = cpi.authority;
8878        if (cpiAuth.indexOf(';') == -1) {
8879            return cpiAuth.equals(uriAuth);
8880        }
8881        String[] cpiAuths = cpiAuth.split(";");
8882        int length = cpiAuths.length;
8883        for (int i = 0; i < length; i++) {
8884            if (cpiAuths[i].equals(uriAuth)) return true;
8885        }
8886        return false;
8887    }
8888
8889    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8890            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8891        if (r != null) {
8892            for (int i=0; i<r.conProviders.size(); i++) {
8893                ContentProviderConnection conn = r.conProviders.get(i);
8894                if (conn.provider == cpr) {
8895                    if (DEBUG_PROVIDER) Slog.v(TAG,
8896                            "Adding provider requested by "
8897                            + r.processName + " from process "
8898                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8899                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8900                    if (stable) {
8901                        conn.stableCount++;
8902                        conn.numStableIncs++;
8903                    } else {
8904                        conn.unstableCount++;
8905                        conn.numUnstableIncs++;
8906                    }
8907                    return conn;
8908                }
8909            }
8910            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8911            if (stable) {
8912                conn.stableCount = 1;
8913                conn.numStableIncs = 1;
8914            } else {
8915                conn.unstableCount = 1;
8916                conn.numUnstableIncs = 1;
8917            }
8918            cpr.connections.add(conn);
8919            r.conProviders.add(conn);
8920            return conn;
8921        }
8922        cpr.addExternalProcessHandleLocked(externalProcessToken);
8923        return null;
8924    }
8925
8926    boolean decProviderCountLocked(ContentProviderConnection conn,
8927            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8928        if (conn != null) {
8929            cpr = conn.provider;
8930            if (DEBUG_PROVIDER) Slog.v(TAG,
8931                    "Removing provider requested by "
8932                    + conn.client.processName + " from process "
8933                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8934                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8935            if (stable) {
8936                conn.stableCount--;
8937            } else {
8938                conn.unstableCount--;
8939            }
8940            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8941                cpr.connections.remove(conn);
8942                conn.client.conProviders.remove(conn);
8943                return true;
8944            }
8945            return false;
8946        }
8947        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8948        return false;
8949    }
8950
8951    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8952            String name, IBinder token, boolean stable, int userId) {
8953        ContentProviderRecord cpr;
8954        ContentProviderConnection conn = null;
8955        ProviderInfo cpi = null;
8956
8957        synchronized(this) {
8958            ProcessRecord r = null;
8959            if (caller != null) {
8960                r = getRecordForAppLocked(caller);
8961                if (r == null) {
8962                    throw new SecurityException(
8963                            "Unable to find app for caller " + caller
8964                          + " (pid=" + Binder.getCallingPid()
8965                          + ") when getting content provider " + name);
8966                }
8967            }
8968
8969            boolean checkCrossUser = true;
8970
8971            // First check if this content provider has been published...
8972            cpr = mProviderMap.getProviderByName(name, userId);
8973            // If that didn't work, check if it exists for user 0 and then
8974            // verify that it's a singleton provider before using it.
8975            if (cpr == null && userId != UserHandle.USER_OWNER) {
8976                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8977                if (cpr != null) {
8978                    cpi = cpr.info;
8979                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8980                            cpi.name, cpi.flags)
8981                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8982                        userId = UserHandle.USER_OWNER;
8983                        checkCrossUser = false;
8984                    } else {
8985                        cpr = null;
8986                        cpi = null;
8987                    }
8988                }
8989            }
8990
8991            boolean providerRunning = cpr != null;
8992            if (providerRunning) {
8993                cpi = cpr.info;
8994                String msg;
8995                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8996                        != null) {
8997                    throw new SecurityException(msg);
8998                }
8999
9000                if (r != null && cpr.canRunHere(r)) {
9001                    // This provider has been published or is in the process
9002                    // of being published...  but it is also allowed to run
9003                    // in the caller's process, so don't make a connection
9004                    // and just let the caller instantiate its own instance.
9005                    ContentProviderHolder holder = cpr.newHolder(null);
9006                    // don't give caller the provider object, it needs
9007                    // to make its own.
9008                    holder.provider = null;
9009                    return holder;
9010                }
9011
9012                final long origId = Binder.clearCallingIdentity();
9013
9014                // In this case the provider instance already exists, so we can
9015                // return it right away.
9016                conn = incProviderCountLocked(r, cpr, token, stable);
9017                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9018                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9019                        // If this is a perceptible app accessing the provider,
9020                        // make sure to count it as being accessed and thus
9021                        // back up on the LRU list.  This is good because
9022                        // content providers are often expensive to start.
9023                        updateLruProcessLocked(cpr.proc, false, null);
9024                    }
9025                }
9026
9027                if (cpr.proc != null) {
9028                    if (false) {
9029                        if (cpr.name.flattenToShortString().equals(
9030                                "com.android.providers.calendar/.CalendarProvider2")) {
9031                            Slog.v(TAG, "****************** KILLING "
9032                                + cpr.name.flattenToShortString());
9033                            Process.killProcess(cpr.proc.pid);
9034                        }
9035                    }
9036                    boolean success = updateOomAdjLocked(cpr.proc);
9037                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9038                    // NOTE: there is still a race here where a signal could be
9039                    // pending on the process even though we managed to update its
9040                    // adj level.  Not sure what to do about this, but at least
9041                    // the race is now smaller.
9042                    if (!success) {
9043                        // Uh oh...  it looks like the provider's process
9044                        // has been killed on us.  We need to wait for a new
9045                        // process to be started, and make sure its death
9046                        // doesn't kill our process.
9047                        Slog.i(TAG,
9048                                "Existing provider " + cpr.name.flattenToShortString()
9049                                + " is crashing; detaching " + r);
9050                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9051                        appDiedLocked(cpr.proc);
9052                        if (!lastRef) {
9053                            // This wasn't the last ref our process had on
9054                            // the provider...  we have now been killed, bail.
9055                            return null;
9056                        }
9057                        providerRunning = false;
9058                        conn = null;
9059                    }
9060                }
9061
9062                Binder.restoreCallingIdentity(origId);
9063            }
9064
9065            boolean singleton;
9066            if (!providerRunning) {
9067                try {
9068                    cpi = AppGlobals.getPackageManager().
9069                        resolveContentProvider(name,
9070                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9071                } catch (RemoteException ex) {
9072                }
9073                if (cpi == null) {
9074                    return null;
9075                }
9076                // If the provider is a singleton AND
9077                // (it's a call within the same user || the provider is a
9078                // privileged app)
9079                // Then allow connecting to the singleton provider
9080                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9081                        cpi.name, cpi.flags)
9082                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9083                if (singleton) {
9084                    userId = UserHandle.USER_OWNER;
9085                }
9086                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9087
9088                String msg;
9089                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9090                        != null) {
9091                    throw new SecurityException(msg);
9092                }
9093
9094                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9095                        && !cpi.processName.equals("system")) {
9096                    // If this content provider does not run in the system
9097                    // process, and the system is not yet ready to run other
9098                    // processes, then fail fast instead of hanging.
9099                    throw new IllegalArgumentException(
9100                            "Attempt to launch content provider before system ready");
9101                }
9102
9103                // Make sure that the user who owns this provider is started.  If not,
9104                // we don't want to allow it to run.
9105                if (mStartedUsers.get(userId) == null) {
9106                    Slog.w(TAG, "Unable to launch app "
9107                            + cpi.applicationInfo.packageName + "/"
9108                            + cpi.applicationInfo.uid + " for provider "
9109                            + name + ": user " + userId + " is stopped");
9110                    return null;
9111                }
9112
9113                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9114                cpr = mProviderMap.getProviderByClass(comp, userId);
9115                final boolean firstClass = cpr == null;
9116                if (firstClass) {
9117                    try {
9118                        ApplicationInfo ai =
9119                            AppGlobals.getPackageManager().
9120                                getApplicationInfo(
9121                                        cpi.applicationInfo.packageName,
9122                                        STOCK_PM_FLAGS, userId);
9123                        if (ai == null) {
9124                            Slog.w(TAG, "No package info for content provider "
9125                                    + cpi.name);
9126                            return null;
9127                        }
9128                        ai = getAppInfoForUser(ai, userId);
9129                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9130                    } catch (RemoteException ex) {
9131                        // pm is in same process, this will never happen.
9132                    }
9133                }
9134
9135                if (r != null && cpr.canRunHere(r)) {
9136                    // If this is a multiprocess provider, then just return its
9137                    // info and allow the caller to instantiate it.  Only do
9138                    // this if the provider is the same user as the caller's
9139                    // process, or can run as root (so can be in any process).
9140                    return cpr.newHolder(null);
9141                }
9142
9143                if (DEBUG_PROVIDER) {
9144                    RuntimeException e = new RuntimeException("here");
9145                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9146                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9147                }
9148
9149                // This is single process, and our app is now connecting to it.
9150                // See if we are already in the process of launching this
9151                // provider.
9152                final int N = mLaunchingProviders.size();
9153                int i;
9154                for (i=0; i<N; i++) {
9155                    if (mLaunchingProviders.get(i) == cpr) {
9156                        break;
9157                    }
9158                }
9159
9160                // If the provider is not already being launched, then get it
9161                // started.
9162                if (i >= N) {
9163                    final long origId = Binder.clearCallingIdentity();
9164
9165                    try {
9166                        // Content provider is now in use, its package can't be stopped.
9167                        try {
9168                            AppGlobals.getPackageManager().setPackageStoppedState(
9169                                    cpr.appInfo.packageName, false, userId);
9170                        } catch (RemoteException e) {
9171                        } catch (IllegalArgumentException e) {
9172                            Slog.w(TAG, "Failed trying to unstop package "
9173                                    + cpr.appInfo.packageName + ": " + e);
9174                        }
9175
9176                        // Use existing process if already started
9177                        ProcessRecord proc = getProcessRecordLocked(
9178                                cpi.processName, cpr.appInfo.uid, false);
9179                        if (proc != null && proc.thread != null) {
9180                            if (DEBUG_PROVIDER) {
9181                                Slog.d(TAG, "Installing in existing process " + proc);
9182                            }
9183                            proc.pubProviders.put(cpi.name, cpr);
9184                            try {
9185                                proc.thread.scheduleInstallProvider(cpi);
9186                            } catch (RemoteException e) {
9187                            }
9188                        } else {
9189                            proc = startProcessLocked(cpi.processName,
9190                                    cpr.appInfo, false, 0, "content provider",
9191                                    new ComponentName(cpi.applicationInfo.packageName,
9192                                            cpi.name), false, false, false);
9193                            if (proc == null) {
9194                                Slog.w(TAG, "Unable to launch app "
9195                                        + cpi.applicationInfo.packageName + "/"
9196                                        + cpi.applicationInfo.uid + " for provider "
9197                                        + name + ": process is bad");
9198                                return null;
9199                            }
9200                        }
9201                        cpr.launchingApp = proc;
9202                        mLaunchingProviders.add(cpr);
9203                    } finally {
9204                        Binder.restoreCallingIdentity(origId);
9205                    }
9206                }
9207
9208                // Make sure the provider is published (the same provider class
9209                // may be published under multiple names).
9210                if (firstClass) {
9211                    mProviderMap.putProviderByClass(comp, cpr);
9212                }
9213
9214                mProviderMap.putProviderByName(name, cpr);
9215                conn = incProviderCountLocked(r, cpr, token, stable);
9216                if (conn != null) {
9217                    conn.waiting = true;
9218                }
9219            }
9220        }
9221
9222        // Wait for the provider to be published...
9223        synchronized (cpr) {
9224            while (cpr.provider == null) {
9225                if (cpr.launchingApp == null) {
9226                    Slog.w(TAG, "Unable to launch app "
9227                            + cpi.applicationInfo.packageName + "/"
9228                            + cpi.applicationInfo.uid + " for provider "
9229                            + name + ": launching app became null");
9230                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9231                            UserHandle.getUserId(cpi.applicationInfo.uid),
9232                            cpi.applicationInfo.packageName,
9233                            cpi.applicationInfo.uid, name);
9234                    return null;
9235                }
9236                try {
9237                    if (DEBUG_MU) {
9238                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9239                                + cpr.launchingApp);
9240                    }
9241                    if (conn != null) {
9242                        conn.waiting = true;
9243                    }
9244                    cpr.wait();
9245                } catch (InterruptedException ex) {
9246                } finally {
9247                    if (conn != null) {
9248                        conn.waiting = false;
9249                    }
9250                }
9251            }
9252        }
9253        return cpr != null ? cpr.newHolder(conn) : null;
9254    }
9255
9256    @Override
9257    public final ContentProviderHolder getContentProvider(
9258            IApplicationThread caller, String name, int userId, boolean stable) {
9259        enforceNotIsolatedCaller("getContentProvider");
9260        if (caller == null) {
9261            String msg = "null IApplicationThread when getting content provider "
9262                    + name;
9263            Slog.w(TAG, msg);
9264            throw new SecurityException(msg);
9265        }
9266        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9267        // with cross-user grant.
9268        return getContentProviderImpl(caller, name, null, stable, userId);
9269    }
9270
9271    public ContentProviderHolder getContentProviderExternal(
9272            String name, int userId, IBinder token) {
9273        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9274            "Do not have permission in call getContentProviderExternal()");
9275        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9276                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9277        return getContentProviderExternalUnchecked(name, token, userId);
9278    }
9279
9280    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9281            IBinder token, int userId) {
9282        return getContentProviderImpl(null, name, token, true, userId);
9283    }
9284
9285    /**
9286     * Drop a content provider from a ProcessRecord's bookkeeping
9287     */
9288    public void removeContentProvider(IBinder connection, boolean stable) {
9289        enforceNotIsolatedCaller("removeContentProvider");
9290        long ident = Binder.clearCallingIdentity();
9291        try {
9292            synchronized (this) {
9293                ContentProviderConnection conn;
9294                try {
9295                    conn = (ContentProviderConnection)connection;
9296                } catch (ClassCastException e) {
9297                    String msg ="removeContentProvider: " + connection
9298                            + " not a ContentProviderConnection";
9299                    Slog.w(TAG, msg);
9300                    throw new IllegalArgumentException(msg);
9301                }
9302                if (conn == null) {
9303                    throw new NullPointerException("connection is null");
9304                }
9305                if (decProviderCountLocked(conn, null, null, stable)) {
9306                    updateOomAdjLocked();
9307                }
9308            }
9309        } finally {
9310            Binder.restoreCallingIdentity(ident);
9311        }
9312    }
9313
9314    public void removeContentProviderExternal(String name, IBinder token) {
9315        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9316            "Do not have permission in call removeContentProviderExternal()");
9317        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
9318    }
9319
9320    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9321        synchronized (this) {
9322            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9323            if(cpr == null) {
9324                //remove from mProvidersByClass
9325                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9326                return;
9327            }
9328
9329            //update content provider record entry info
9330            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9331            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9332            if (localCpr.hasExternalProcessHandles()) {
9333                if (localCpr.removeExternalProcessHandleLocked(token)) {
9334                    updateOomAdjLocked();
9335                } else {
9336                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9337                            + " with no external reference for token: "
9338                            + token + ".");
9339                }
9340            } else {
9341                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9342                        + " with no external references.");
9343            }
9344        }
9345    }
9346
9347    public final void publishContentProviders(IApplicationThread caller,
9348            List<ContentProviderHolder> providers) {
9349        if (providers == null) {
9350            return;
9351        }
9352
9353        enforceNotIsolatedCaller("publishContentProviders");
9354        synchronized (this) {
9355            final ProcessRecord r = getRecordForAppLocked(caller);
9356            if (DEBUG_MU)
9357                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9358            if (r == null) {
9359                throw new SecurityException(
9360                        "Unable to find app for caller " + caller
9361                      + " (pid=" + Binder.getCallingPid()
9362                      + ") when publishing content providers");
9363            }
9364
9365            final long origId = Binder.clearCallingIdentity();
9366
9367            final int N = providers.size();
9368            for (int i=0; i<N; i++) {
9369                ContentProviderHolder src = providers.get(i);
9370                if (src == null || src.info == null || src.provider == null) {
9371                    continue;
9372                }
9373                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9374                if (DEBUG_MU)
9375                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9376                if (dst != null) {
9377                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9378                    mProviderMap.putProviderByClass(comp, dst);
9379                    String names[] = dst.info.authority.split(";");
9380                    for (int j = 0; j < names.length; j++) {
9381                        mProviderMap.putProviderByName(names[j], dst);
9382                    }
9383
9384                    int NL = mLaunchingProviders.size();
9385                    int j;
9386                    for (j=0; j<NL; j++) {
9387                        if (mLaunchingProviders.get(j) == dst) {
9388                            mLaunchingProviders.remove(j);
9389                            j--;
9390                            NL--;
9391                        }
9392                    }
9393                    synchronized (dst) {
9394                        dst.provider = src.provider;
9395                        dst.proc = r;
9396                        dst.notifyAll();
9397                    }
9398                    updateOomAdjLocked(r);
9399                }
9400            }
9401
9402            Binder.restoreCallingIdentity(origId);
9403        }
9404    }
9405
9406    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9407        ContentProviderConnection conn;
9408        try {
9409            conn = (ContentProviderConnection)connection;
9410        } catch (ClassCastException e) {
9411            String msg ="refContentProvider: " + connection
9412                    + " not a ContentProviderConnection";
9413            Slog.w(TAG, msg);
9414            throw new IllegalArgumentException(msg);
9415        }
9416        if (conn == null) {
9417            throw new NullPointerException("connection is null");
9418        }
9419
9420        synchronized (this) {
9421            if (stable > 0) {
9422                conn.numStableIncs += stable;
9423            }
9424            stable = conn.stableCount + stable;
9425            if (stable < 0) {
9426                throw new IllegalStateException("stableCount < 0: " + stable);
9427            }
9428
9429            if (unstable > 0) {
9430                conn.numUnstableIncs += unstable;
9431            }
9432            unstable = conn.unstableCount + unstable;
9433            if (unstable < 0) {
9434                throw new IllegalStateException("unstableCount < 0: " + unstable);
9435            }
9436
9437            if ((stable+unstable) <= 0) {
9438                throw new IllegalStateException("ref counts can't go to zero here: stable="
9439                        + stable + " unstable=" + unstable);
9440            }
9441            conn.stableCount = stable;
9442            conn.unstableCount = unstable;
9443            return !conn.dead;
9444        }
9445    }
9446
9447    public void unstableProviderDied(IBinder connection) {
9448        ContentProviderConnection conn;
9449        try {
9450            conn = (ContentProviderConnection)connection;
9451        } catch (ClassCastException e) {
9452            String msg ="refContentProvider: " + connection
9453                    + " not a ContentProviderConnection";
9454            Slog.w(TAG, msg);
9455            throw new IllegalArgumentException(msg);
9456        }
9457        if (conn == null) {
9458            throw new NullPointerException("connection is null");
9459        }
9460
9461        // Safely retrieve the content provider associated with the connection.
9462        IContentProvider provider;
9463        synchronized (this) {
9464            provider = conn.provider.provider;
9465        }
9466
9467        if (provider == null) {
9468            // Um, yeah, we're way ahead of you.
9469            return;
9470        }
9471
9472        // Make sure the caller is being honest with us.
9473        if (provider.asBinder().pingBinder()) {
9474            // Er, no, still looks good to us.
9475            synchronized (this) {
9476                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9477                        + " says " + conn + " died, but we don't agree");
9478                return;
9479            }
9480        }
9481
9482        // Well look at that!  It's dead!
9483        synchronized (this) {
9484            if (conn.provider.provider != provider) {
9485                // But something changed...  good enough.
9486                return;
9487            }
9488
9489            ProcessRecord proc = conn.provider.proc;
9490            if (proc == null || proc.thread == null) {
9491                // Seems like the process is already cleaned up.
9492                return;
9493            }
9494
9495            // As far as we're concerned, this is just like receiving a
9496            // death notification...  just a bit prematurely.
9497            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9498                    + ") early provider death");
9499            final long ident = Binder.clearCallingIdentity();
9500            try {
9501                appDiedLocked(proc);
9502            } finally {
9503                Binder.restoreCallingIdentity(ident);
9504            }
9505        }
9506    }
9507
9508    @Override
9509    public void appNotRespondingViaProvider(IBinder connection) {
9510        enforceCallingPermission(
9511                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9512
9513        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9514        if (conn == null) {
9515            Slog.w(TAG, "ContentProviderConnection is null");
9516            return;
9517        }
9518
9519        final ProcessRecord host = conn.provider.proc;
9520        if (host == null) {
9521            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9522            return;
9523        }
9524
9525        final long token = Binder.clearCallingIdentity();
9526        try {
9527            appNotResponding(host, null, null, false, "ContentProvider not responding");
9528        } finally {
9529            Binder.restoreCallingIdentity(token);
9530        }
9531    }
9532
9533    public final void installSystemProviders() {
9534        List<ProviderInfo> providers;
9535        synchronized (this) {
9536            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9537            providers = generateApplicationProvidersLocked(app);
9538            if (providers != null) {
9539                for (int i=providers.size()-1; i>=0; i--) {
9540                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9541                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9542                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9543                                + ": not system .apk");
9544                        providers.remove(i);
9545                    }
9546                }
9547            }
9548        }
9549        if (providers != null) {
9550            mSystemThread.installSystemProviders(providers);
9551        }
9552
9553        mCoreSettingsObserver = new CoreSettingsObserver(this);
9554
9555        //mUsageStatsService.monitorPackages();
9556    }
9557
9558    /**
9559     * Allows apps to retrieve the MIME type of a URI.
9560     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9561     * users, then it does not need permission to access the ContentProvider.
9562     * Either, it needs cross-user uri grants.
9563     *
9564     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9565     *
9566     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9567     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9568     */
9569    public String getProviderMimeType(Uri uri, int userId) {
9570        enforceNotIsolatedCaller("getProviderMimeType");
9571        final String name = uri.getAuthority();
9572        int callingUid = Binder.getCallingUid();
9573        int callingPid = Binder.getCallingPid();
9574        long ident = 0;
9575        boolean clearedIdentity = false;
9576        userId = unsafeConvertIncomingUser(userId);
9577        if (UserHandle.getUserId(callingUid) != userId) {
9578            if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9579                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9580                    || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9581                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9582                clearedIdentity = true;
9583                ident = Binder.clearCallingIdentity();
9584            }
9585        }
9586        ContentProviderHolder holder = null;
9587        try {
9588            holder = getContentProviderExternalUnchecked(name, null, userId);
9589            if (holder != null) {
9590                return holder.provider.getType(uri);
9591            }
9592        } catch (RemoteException e) {
9593            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9594            return null;
9595        } finally {
9596            // We need to clear the identity to call removeContentProviderExternalUnchecked
9597            if (!clearedIdentity) {
9598                ident = Binder.clearCallingIdentity();
9599            }
9600            try {
9601                if (holder != null) {
9602                    removeContentProviderExternalUnchecked(name, null, userId);
9603                }
9604            } finally {
9605                Binder.restoreCallingIdentity(ident);
9606            }
9607        }
9608
9609        return null;
9610    }
9611
9612    // =========================================================
9613    // GLOBAL MANAGEMENT
9614    // =========================================================
9615
9616    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9617            boolean isolated, int isolatedUid) {
9618        String proc = customProcess != null ? customProcess : info.processName;
9619        BatteryStatsImpl.Uid.Proc ps = null;
9620        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9621        int uid = info.uid;
9622        if (isolated) {
9623            if (isolatedUid == 0) {
9624                int userId = UserHandle.getUserId(uid);
9625                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9626                while (true) {
9627                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9628                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9629                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9630                    }
9631                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9632                    mNextIsolatedProcessUid++;
9633                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9634                        // No process for this uid, use it.
9635                        break;
9636                    }
9637                    stepsLeft--;
9638                    if (stepsLeft <= 0) {
9639                        return null;
9640                    }
9641                }
9642            } else {
9643                // Special case for startIsolatedProcess (internal only), where
9644                // the uid of the isolated process is specified by the caller.
9645                uid = isolatedUid;
9646            }
9647        }
9648        return new ProcessRecord(stats, info, proc, uid);
9649    }
9650
9651    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9652            String abiOverride) {
9653        ProcessRecord app;
9654        if (!isolated) {
9655            app = getProcessRecordLocked(info.processName, info.uid, true);
9656        } else {
9657            app = null;
9658        }
9659
9660        if (app == null) {
9661            app = newProcessRecordLocked(info, null, isolated, 0);
9662            mProcessNames.put(info.processName, app.uid, app);
9663            if (isolated) {
9664                mIsolatedProcesses.put(app.uid, app);
9665            }
9666            updateLruProcessLocked(app, false, null);
9667            updateOomAdjLocked();
9668        }
9669
9670        // This package really, really can not be stopped.
9671        try {
9672            AppGlobals.getPackageManager().setPackageStoppedState(
9673                    info.packageName, false, UserHandle.getUserId(app.uid));
9674        } catch (RemoteException e) {
9675        } catch (IllegalArgumentException e) {
9676            Slog.w(TAG, "Failed trying to unstop package "
9677                    + info.packageName + ": " + e);
9678        }
9679
9680        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9681                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9682            app.persistent = true;
9683            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9684        }
9685        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9686            mPersistentStartingProcesses.add(app);
9687            startProcessLocked(app, "added application", app.processName, abiOverride,
9688                    null /* entryPoint */, null /* entryPointArgs */);
9689        }
9690
9691        return app;
9692    }
9693
9694    public void unhandledBack() {
9695        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9696                "unhandledBack()");
9697
9698        synchronized(this) {
9699            final long origId = Binder.clearCallingIdentity();
9700            try {
9701                getFocusedStack().unhandledBackLocked();
9702            } finally {
9703                Binder.restoreCallingIdentity(origId);
9704            }
9705        }
9706    }
9707
9708    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9709        enforceNotIsolatedCaller("openContentUri");
9710        final int userId = UserHandle.getCallingUserId();
9711        String name = uri.getAuthority();
9712        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9713        ParcelFileDescriptor pfd = null;
9714        if (cph != null) {
9715            // We record the binder invoker's uid in thread-local storage before
9716            // going to the content provider to open the file.  Later, in the code
9717            // that handles all permissions checks, we look for this uid and use
9718            // that rather than the Activity Manager's own uid.  The effect is that
9719            // we do the check against the caller's permissions even though it looks
9720            // to the content provider like the Activity Manager itself is making
9721            // the request.
9722            sCallerIdentity.set(new Identity(
9723                    Binder.getCallingPid(), Binder.getCallingUid()));
9724            try {
9725                pfd = cph.provider.openFile(null, uri, "r", null);
9726            } catch (FileNotFoundException e) {
9727                // do nothing; pfd will be returned null
9728            } finally {
9729                // Ensure that whatever happens, we clean up the identity state
9730                sCallerIdentity.remove();
9731            }
9732
9733            // We've got the fd now, so we're done with the provider.
9734            removeContentProviderExternalUnchecked(name, null, userId);
9735        } else {
9736            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9737        }
9738        return pfd;
9739    }
9740
9741    // Actually is sleeping or shutting down or whatever else in the future
9742    // is an inactive state.
9743    public boolean isSleepingOrShuttingDown() {
9744        return mSleeping || mShuttingDown;
9745    }
9746
9747    public boolean isSleeping() {
9748        return mSleeping;
9749    }
9750
9751    void goingToSleep() {
9752        synchronized(this) {
9753            mWentToSleep = true;
9754            updateEventDispatchingLocked();
9755            goToSleepIfNeededLocked();
9756        }
9757    }
9758
9759    void finishRunningVoiceLocked() {
9760        if (mRunningVoice) {
9761            mRunningVoice = false;
9762            goToSleepIfNeededLocked();
9763        }
9764    }
9765
9766    void goToSleepIfNeededLocked() {
9767        if (mWentToSleep && !mRunningVoice) {
9768            if (!mSleeping) {
9769                mSleeping = true;
9770                mStackSupervisor.goingToSleepLocked();
9771
9772                // Initialize the wake times of all processes.
9773                checkExcessivePowerUsageLocked(false);
9774                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9775                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9776                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9777            }
9778        }
9779    }
9780
9781    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9782        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9783            // Never persist the home stack.
9784            return;
9785        }
9786        mTaskPersister.wakeup(task, flush);
9787    }
9788
9789    @Override
9790    public boolean shutdown(int timeout) {
9791        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9792                != PackageManager.PERMISSION_GRANTED) {
9793            throw new SecurityException("Requires permission "
9794                    + android.Manifest.permission.SHUTDOWN);
9795        }
9796
9797        boolean timedout = false;
9798
9799        synchronized(this) {
9800            mShuttingDown = true;
9801            updateEventDispatchingLocked();
9802            timedout = mStackSupervisor.shutdownLocked(timeout);
9803        }
9804
9805        mAppOpsService.shutdown();
9806        if (mUsageStatsService != null) {
9807            mUsageStatsService.prepareShutdown();
9808        }
9809        mBatteryStatsService.shutdown();
9810        synchronized (this) {
9811            mProcessStats.shutdownLocked();
9812        }
9813        notifyTaskPersisterLocked(null, true);
9814
9815        return timedout;
9816    }
9817
9818    public final void activitySlept(IBinder token) {
9819        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9820
9821        final long origId = Binder.clearCallingIdentity();
9822
9823        synchronized (this) {
9824            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9825            if (r != null) {
9826                mStackSupervisor.activitySleptLocked(r);
9827            }
9828        }
9829
9830        Binder.restoreCallingIdentity(origId);
9831    }
9832
9833    void logLockScreen(String msg) {
9834        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9835                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9836                mWentToSleep + " mSleeping=" + mSleeping);
9837    }
9838
9839    private void comeOutOfSleepIfNeededLocked() {
9840        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9841            if (mSleeping) {
9842                mSleeping = false;
9843                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9844            }
9845        }
9846    }
9847
9848    void wakingUp() {
9849        synchronized(this) {
9850            mWentToSleep = false;
9851            updateEventDispatchingLocked();
9852            comeOutOfSleepIfNeededLocked();
9853        }
9854    }
9855
9856    void startRunningVoiceLocked() {
9857        if (!mRunningVoice) {
9858            mRunningVoice = true;
9859            comeOutOfSleepIfNeededLocked();
9860        }
9861    }
9862
9863    private void updateEventDispatchingLocked() {
9864        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
9865    }
9866
9867    public void setLockScreenShown(boolean shown) {
9868        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9869                != PackageManager.PERMISSION_GRANTED) {
9870            throw new SecurityException("Requires permission "
9871                    + android.Manifest.permission.DEVICE_POWER);
9872        }
9873
9874        synchronized(this) {
9875            long ident = Binder.clearCallingIdentity();
9876            try {
9877                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9878                mLockScreenShown = shown;
9879                comeOutOfSleepIfNeededLocked();
9880            } finally {
9881                Binder.restoreCallingIdentity(ident);
9882            }
9883        }
9884    }
9885
9886    @Override
9887    public void stopAppSwitches() {
9888        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9889                != PackageManager.PERMISSION_GRANTED) {
9890            throw new SecurityException("Requires permission "
9891                    + android.Manifest.permission.STOP_APP_SWITCHES);
9892        }
9893
9894        synchronized(this) {
9895            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9896                    + APP_SWITCH_DELAY_TIME;
9897            mDidAppSwitch = false;
9898            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9899            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9900            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9901        }
9902    }
9903
9904    public void resumeAppSwitches() {
9905        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9906                != PackageManager.PERMISSION_GRANTED) {
9907            throw new SecurityException("Requires permission "
9908                    + android.Manifest.permission.STOP_APP_SWITCHES);
9909        }
9910
9911        synchronized(this) {
9912            // Note that we don't execute any pending app switches... we will
9913            // let those wait until either the timeout, or the next start
9914            // activity request.
9915            mAppSwitchesAllowedTime = 0;
9916        }
9917    }
9918
9919    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9920            String name) {
9921        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9922            return true;
9923        }
9924
9925        final int perm = checkComponentPermission(
9926                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9927                callingUid, -1, true);
9928        if (perm == PackageManager.PERMISSION_GRANTED) {
9929            return true;
9930        }
9931
9932        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9933        return false;
9934    }
9935
9936    public void setDebugApp(String packageName, boolean waitForDebugger,
9937            boolean persistent) {
9938        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9939                "setDebugApp()");
9940
9941        long ident = Binder.clearCallingIdentity();
9942        try {
9943            // Note that this is not really thread safe if there are multiple
9944            // callers into it at the same time, but that's not a situation we
9945            // care about.
9946            if (persistent) {
9947                final ContentResolver resolver = mContext.getContentResolver();
9948                Settings.Global.putString(
9949                    resolver, Settings.Global.DEBUG_APP,
9950                    packageName);
9951                Settings.Global.putInt(
9952                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9953                    waitForDebugger ? 1 : 0);
9954            }
9955
9956            synchronized (this) {
9957                if (!persistent) {
9958                    mOrigDebugApp = mDebugApp;
9959                    mOrigWaitForDebugger = mWaitForDebugger;
9960                }
9961                mDebugApp = packageName;
9962                mWaitForDebugger = waitForDebugger;
9963                mDebugTransient = !persistent;
9964                if (packageName != null) {
9965                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9966                            false, UserHandle.USER_ALL, "set debug app");
9967                }
9968            }
9969        } finally {
9970            Binder.restoreCallingIdentity(ident);
9971        }
9972    }
9973
9974    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9975        synchronized (this) {
9976            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9977            if (!isDebuggable) {
9978                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9979                    throw new SecurityException("Process not debuggable: " + app.packageName);
9980                }
9981            }
9982
9983            mOpenGlTraceApp = processName;
9984        }
9985    }
9986
9987    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9988            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9989        synchronized (this) {
9990            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9991            if (!isDebuggable) {
9992                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9993                    throw new SecurityException("Process not debuggable: " + app.packageName);
9994                }
9995            }
9996            mProfileApp = processName;
9997            mProfileFile = profileFile;
9998            if (mProfileFd != null) {
9999                try {
10000                    mProfileFd.close();
10001                } catch (IOException e) {
10002                }
10003                mProfileFd = null;
10004            }
10005            mProfileFd = profileFd;
10006            mProfileType = 0;
10007            mAutoStopProfiler = autoStopProfiler;
10008        }
10009    }
10010
10011    @Override
10012    public void setAlwaysFinish(boolean enabled) {
10013        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10014                "setAlwaysFinish()");
10015
10016        Settings.Global.putInt(
10017                mContext.getContentResolver(),
10018                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10019
10020        synchronized (this) {
10021            mAlwaysFinishActivities = enabled;
10022        }
10023    }
10024
10025    @Override
10026    public void setActivityController(IActivityController controller) {
10027        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10028                "setActivityController()");
10029        synchronized (this) {
10030            mController = controller;
10031            Watchdog.getInstance().setActivityController(controller);
10032        }
10033    }
10034
10035    @Override
10036    public void setUserIsMonkey(boolean userIsMonkey) {
10037        synchronized (this) {
10038            synchronized (mPidsSelfLocked) {
10039                final int callingPid = Binder.getCallingPid();
10040                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10041                if (precessRecord == null) {
10042                    throw new SecurityException("Unknown process: " + callingPid);
10043                }
10044                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10045                    throw new SecurityException("Only an instrumentation process "
10046                            + "with a UiAutomation can call setUserIsMonkey");
10047                }
10048            }
10049            mUserIsMonkey = userIsMonkey;
10050        }
10051    }
10052
10053    @Override
10054    public boolean isUserAMonkey() {
10055        synchronized (this) {
10056            // If there is a controller also implies the user is a monkey.
10057            return (mUserIsMonkey || mController != null);
10058        }
10059    }
10060
10061    public void requestBugReport() {
10062        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10063        SystemProperties.set("ctl.start", "bugreport");
10064    }
10065
10066    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10067        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10068    }
10069
10070    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10071        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10072            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10073        }
10074        return KEY_DISPATCHING_TIMEOUT;
10075    }
10076
10077    @Override
10078    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10079        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10080                != PackageManager.PERMISSION_GRANTED) {
10081            throw new SecurityException("Requires permission "
10082                    + android.Manifest.permission.FILTER_EVENTS);
10083        }
10084        ProcessRecord proc;
10085        long timeout;
10086        synchronized (this) {
10087            synchronized (mPidsSelfLocked) {
10088                proc = mPidsSelfLocked.get(pid);
10089            }
10090            timeout = getInputDispatchingTimeoutLocked(proc);
10091        }
10092
10093        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10094            return -1;
10095        }
10096
10097        return timeout;
10098    }
10099
10100    /**
10101     * Handle input dispatching timeouts.
10102     * Returns whether input dispatching should be aborted or not.
10103     */
10104    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10105            final ActivityRecord activity, final ActivityRecord parent,
10106            final boolean aboveSystem, String reason) {
10107        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10108                != PackageManager.PERMISSION_GRANTED) {
10109            throw new SecurityException("Requires permission "
10110                    + android.Manifest.permission.FILTER_EVENTS);
10111        }
10112
10113        final String annotation;
10114        if (reason == null) {
10115            annotation = "Input dispatching timed out";
10116        } else {
10117            annotation = "Input dispatching timed out (" + reason + ")";
10118        }
10119
10120        if (proc != null) {
10121            synchronized (this) {
10122                if (proc.debugging) {
10123                    return false;
10124                }
10125
10126                if (mDidDexOpt) {
10127                    // Give more time since we were dexopting.
10128                    mDidDexOpt = false;
10129                    return false;
10130                }
10131
10132                if (proc.instrumentationClass != null) {
10133                    Bundle info = new Bundle();
10134                    info.putString("shortMsg", "keyDispatchingTimedOut");
10135                    info.putString("longMsg", annotation);
10136                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10137                    return true;
10138                }
10139            }
10140            mHandler.post(new Runnable() {
10141                @Override
10142                public void run() {
10143                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10144                }
10145            });
10146        }
10147
10148        return true;
10149    }
10150
10151    public Bundle getAssistContextExtras(int requestType) {
10152        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10153                "getAssistContextExtras()");
10154        PendingAssistExtras pae;
10155        Bundle extras = new Bundle();
10156        synchronized (this) {
10157            ActivityRecord activity = getFocusedStack().mResumedActivity;
10158            if (activity == null) {
10159                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10160                return null;
10161            }
10162            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10163            if (activity.app == null || activity.app.thread == null) {
10164                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10165                return extras;
10166            }
10167            if (activity.app.pid == Binder.getCallingPid()) {
10168                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10169                return extras;
10170            }
10171            pae = new PendingAssistExtras(activity);
10172            try {
10173                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10174                        requestType);
10175                mPendingAssistExtras.add(pae);
10176                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10177            } catch (RemoteException e) {
10178                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10179                return extras;
10180            }
10181        }
10182        synchronized (pae) {
10183            while (!pae.haveResult) {
10184                try {
10185                    pae.wait();
10186                } catch (InterruptedException e) {
10187                }
10188            }
10189            if (pae.result != null) {
10190                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10191            }
10192        }
10193        synchronized (this) {
10194            mPendingAssistExtras.remove(pae);
10195            mHandler.removeCallbacks(pae);
10196        }
10197        return extras;
10198    }
10199
10200    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10201        PendingAssistExtras pae = (PendingAssistExtras)token;
10202        synchronized (pae) {
10203            pae.result = extras;
10204            pae.haveResult = true;
10205            pae.notifyAll();
10206        }
10207    }
10208
10209    public void registerProcessObserver(IProcessObserver observer) {
10210        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10211                "registerProcessObserver()");
10212        synchronized (this) {
10213            mProcessObservers.register(observer);
10214        }
10215    }
10216
10217    @Override
10218    public void unregisterProcessObserver(IProcessObserver observer) {
10219        synchronized (this) {
10220            mProcessObservers.unregister(observer);
10221        }
10222    }
10223
10224    @Override
10225    public boolean convertFromTranslucent(IBinder token) {
10226        final long origId = Binder.clearCallingIdentity();
10227        try {
10228            synchronized (this) {
10229                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10230                if (r == null) {
10231                    return false;
10232                }
10233                if (r.changeWindowTranslucency(true)) {
10234                    mWindowManager.setAppFullscreen(token, true);
10235                    r.task.stack.releaseBackgroundResources();
10236                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10237                    return true;
10238                }
10239                return false;
10240            }
10241        } finally {
10242            Binder.restoreCallingIdentity(origId);
10243        }
10244    }
10245
10246    @Override
10247    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10248        final long origId = Binder.clearCallingIdentity();
10249        try {
10250            synchronized (this) {
10251                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10252                if (r == null) {
10253                    return false;
10254                }
10255                int index = r.task.mActivities.lastIndexOf(r);
10256                if (index > 0) {
10257                    ActivityRecord under = r.task.mActivities.get(index - 1);
10258                    under.returningOptions = options;
10259                }
10260                if (r.changeWindowTranslucency(false)) {
10261                    r.task.stack.convertToTranslucent(r);
10262                    mWindowManager.setAppFullscreen(token, false);
10263                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10264                    return true;
10265                } else {
10266                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10267                    return false;
10268                }
10269            }
10270        } finally {
10271            Binder.restoreCallingIdentity(origId);
10272        }
10273    }
10274
10275    @Override
10276    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10277        final long origId = Binder.clearCallingIdentity();
10278        try {
10279            synchronized (this) {
10280                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10281                if (r != null) {
10282                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10283                }
10284            }
10285            return false;
10286        } finally {
10287            Binder.restoreCallingIdentity(origId);
10288        }
10289    }
10290
10291    @Override
10292    public boolean isBackgroundVisibleBehind(IBinder token) {
10293        final long origId = Binder.clearCallingIdentity();
10294        try {
10295            synchronized (this) {
10296                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10297                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10298                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10299                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10300                return visible;
10301            }
10302        } finally {
10303            Binder.restoreCallingIdentity(origId);
10304        }
10305    }
10306
10307    @Override
10308    public ActivityOptions getActivityOptions(IBinder token) {
10309        final long origId = Binder.clearCallingIdentity();
10310        try {
10311            synchronized (this) {
10312                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10313                if (r != null) {
10314                    final ActivityOptions activityOptions = r.pendingOptions;
10315                    r.pendingOptions = null;
10316                    return activityOptions;
10317                }
10318                return null;
10319            }
10320        } finally {
10321            Binder.restoreCallingIdentity(origId);
10322        }
10323    }
10324
10325    @Override
10326    public void setImmersive(IBinder token, boolean immersive) {
10327        synchronized(this) {
10328            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10329            if (r == null) {
10330                throw new IllegalArgumentException();
10331            }
10332            r.immersive = immersive;
10333
10334            // update associated state if we're frontmost
10335            if (r == mFocusedActivity) {
10336                if (DEBUG_IMMERSIVE) {
10337                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10338                }
10339                applyUpdateLockStateLocked(r);
10340            }
10341        }
10342    }
10343
10344    @Override
10345    public boolean isImmersive(IBinder token) {
10346        synchronized (this) {
10347            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10348            if (r == null) {
10349                throw new IllegalArgumentException();
10350            }
10351            return r.immersive;
10352        }
10353    }
10354
10355    public boolean isTopActivityImmersive() {
10356        enforceNotIsolatedCaller("startActivity");
10357        synchronized (this) {
10358            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10359            return (r != null) ? r.immersive : false;
10360        }
10361    }
10362
10363    @Override
10364    public boolean isTopOfTask(IBinder token) {
10365        synchronized (this) {
10366            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10367            if (r == null) {
10368                throw new IllegalArgumentException();
10369            }
10370            return r.task.getTopActivity() == r;
10371        }
10372    }
10373
10374    public final void enterSafeMode() {
10375        synchronized(this) {
10376            // It only makes sense to do this before the system is ready
10377            // and started launching other packages.
10378            if (!mSystemReady) {
10379                try {
10380                    AppGlobals.getPackageManager().enterSafeMode();
10381                } catch (RemoteException e) {
10382                }
10383            }
10384
10385            mSafeMode = true;
10386        }
10387    }
10388
10389    public final void showSafeModeOverlay() {
10390        View v = LayoutInflater.from(mContext).inflate(
10391                com.android.internal.R.layout.safe_mode, null);
10392        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10393        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10394        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10395        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10396        lp.gravity = Gravity.BOTTOM | Gravity.START;
10397        lp.format = v.getBackground().getOpacity();
10398        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10399                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10400        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10401        ((WindowManager)mContext.getSystemService(
10402                Context.WINDOW_SERVICE)).addView(v, lp);
10403    }
10404
10405    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10406        if (!(sender instanceof PendingIntentRecord)) {
10407            return;
10408        }
10409        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10410        synchronized (stats) {
10411            if (mBatteryStatsService.isOnBattery()) {
10412                mBatteryStatsService.enforceCallingPermission();
10413                PendingIntentRecord rec = (PendingIntentRecord)sender;
10414                int MY_UID = Binder.getCallingUid();
10415                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10416                BatteryStatsImpl.Uid.Pkg pkg =
10417                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10418                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10419                pkg.incWakeupsLocked();
10420            }
10421        }
10422    }
10423
10424    public boolean killPids(int[] pids, String pReason, boolean secure) {
10425        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10426            throw new SecurityException("killPids only available to the system");
10427        }
10428        String reason = (pReason == null) ? "Unknown" : pReason;
10429        // XXX Note: don't acquire main activity lock here, because the window
10430        // manager calls in with its locks held.
10431
10432        boolean killed = false;
10433        synchronized (mPidsSelfLocked) {
10434            int[] types = new int[pids.length];
10435            int worstType = 0;
10436            for (int i=0; i<pids.length; i++) {
10437                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10438                if (proc != null) {
10439                    int type = proc.setAdj;
10440                    types[i] = type;
10441                    if (type > worstType) {
10442                        worstType = type;
10443                    }
10444                }
10445            }
10446
10447            // If the worst oom_adj is somewhere in the cached proc LRU range,
10448            // then constrain it so we will kill all cached procs.
10449            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10450                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10451                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10452            }
10453
10454            // If this is not a secure call, don't let it kill processes that
10455            // are important.
10456            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10457                worstType = ProcessList.SERVICE_ADJ;
10458            }
10459
10460            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10461            for (int i=0; i<pids.length; i++) {
10462                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10463                if (proc == null) {
10464                    continue;
10465                }
10466                int adj = proc.setAdj;
10467                if (adj >= worstType && !proc.killedByAm) {
10468                    proc.kill(reason, true);
10469                    killed = true;
10470                }
10471            }
10472        }
10473        return killed;
10474    }
10475
10476    @Override
10477    public void killUid(int uid, String reason) {
10478        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10479            throw new SecurityException("killUid only available to the system");
10480        }
10481        synchronized (this) {
10482            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10483                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10484                    reason != null ? reason : "kill uid");
10485        }
10486    }
10487
10488    @Override
10489    public boolean killProcessesBelowForeground(String reason) {
10490        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10491            throw new SecurityException("killProcessesBelowForeground() only available to system");
10492        }
10493
10494        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10495    }
10496
10497    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10498        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10499            throw new SecurityException("killProcessesBelowAdj() only available to system");
10500        }
10501
10502        boolean killed = false;
10503        synchronized (mPidsSelfLocked) {
10504            final int size = mPidsSelfLocked.size();
10505            for (int i = 0; i < size; i++) {
10506                final int pid = mPidsSelfLocked.keyAt(i);
10507                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10508                if (proc == null) continue;
10509
10510                final int adj = proc.setAdj;
10511                if (adj > belowAdj && !proc.killedByAm) {
10512                    proc.kill(reason, true);
10513                    killed = true;
10514                }
10515            }
10516        }
10517        return killed;
10518    }
10519
10520    @Override
10521    public void hang(final IBinder who, boolean allowRestart) {
10522        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10523                != PackageManager.PERMISSION_GRANTED) {
10524            throw new SecurityException("Requires permission "
10525                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10526        }
10527
10528        final IBinder.DeathRecipient death = new DeathRecipient() {
10529            @Override
10530            public void binderDied() {
10531                synchronized (this) {
10532                    notifyAll();
10533                }
10534            }
10535        };
10536
10537        try {
10538            who.linkToDeath(death, 0);
10539        } catch (RemoteException e) {
10540            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10541            return;
10542        }
10543
10544        synchronized (this) {
10545            Watchdog.getInstance().setAllowRestart(allowRestart);
10546            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10547            synchronized (death) {
10548                while (who.isBinderAlive()) {
10549                    try {
10550                        death.wait();
10551                    } catch (InterruptedException e) {
10552                    }
10553                }
10554            }
10555            Watchdog.getInstance().setAllowRestart(true);
10556        }
10557    }
10558
10559    @Override
10560    public void restart() {
10561        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10562                != PackageManager.PERMISSION_GRANTED) {
10563            throw new SecurityException("Requires permission "
10564                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10565        }
10566
10567        Log.i(TAG, "Sending shutdown broadcast...");
10568
10569        BroadcastReceiver br = new BroadcastReceiver() {
10570            @Override public void onReceive(Context context, Intent intent) {
10571                // Now the broadcast is done, finish up the low-level shutdown.
10572                Log.i(TAG, "Shutting down activity manager...");
10573                shutdown(10000);
10574                Log.i(TAG, "Shutdown complete, restarting!");
10575                Process.killProcess(Process.myPid());
10576                System.exit(10);
10577            }
10578        };
10579
10580        // First send the high-level shut down broadcast.
10581        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10582        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10583        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10584        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10585        mContext.sendOrderedBroadcastAsUser(intent,
10586                UserHandle.ALL, null, br, mHandler, 0, null, null);
10587        */
10588        br.onReceive(mContext, intent);
10589    }
10590
10591    private long getLowRamTimeSinceIdle(long now) {
10592        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10593    }
10594
10595    @Override
10596    public void performIdleMaintenance() {
10597        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10598                != PackageManager.PERMISSION_GRANTED) {
10599            throw new SecurityException("Requires permission "
10600                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10601        }
10602
10603        synchronized (this) {
10604            final long now = SystemClock.uptimeMillis();
10605            final long timeSinceLastIdle = now - mLastIdleTime;
10606            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10607            mLastIdleTime = now;
10608            mLowRamTimeSinceLastIdle = 0;
10609            if (mLowRamStartTime != 0) {
10610                mLowRamStartTime = now;
10611            }
10612
10613            StringBuilder sb = new StringBuilder(128);
10614            sb.append("Idle maintenance over ");
10615            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10616            sb.append(" low RAM for ");
10617            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10618            Slog.i(TAG, sb.toString());
10619
10620            // If at least 1/3 of our time since the last idle period has been spent
10621            // with RAM low, then we want to kill processes.
10622            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10623
10624            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10625                ProcessRecord proc = mLruProcesses.get(i);
10626                if (proc.notCachedSinceIdle) {
10627                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10628                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10629                        if (doKilling && proc.initialIdlePss != 0
10630                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10631                            proc.kill("idle maint (pss " + proc.lastPss
10632                                    + " from " + proc.initialIdlePss + ")", true);
10633                        }
10634                    }
10635                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10636                    proc.notCachedSinceIdle = true;
10637                    proc.initialIdlePss = 0;
10638                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10639                            isSleeping(), now);
10640                }
10641            }
10642
10643            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10644            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10645        }
10646    }
10647
10648    private void retrieveSettings() {
10649        final ContentResolver resolver = mContext.getContentResolver();
10650        String debugApp = Settings.Global.getString(
10651            resolver, Settings.Global.DEBUG_APP);
10652        boolean waitForDebugger = Settings.Global.getInt(
10653            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10654        boolean alwaysFinishActivities = Settings.Global.getInt(
10655            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10656        boolean forceRtl = Settings.Global.getInt(
10657                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10658        // Transfer any global setting for forcing RTL layout, into a System Property
10659        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10660
10661        Configuration configuration = new Configuration();
10662        Settings.System.getConfiguration(resolver, configuration);
10663        if (forceRtl) {
10664            // This will take care of setting the correct layout direction flags
10665            configuration.setLayoutDirection(configuration.locale);
10666        }
10667
10668        synchronized (this) {
10669            mDebugApp = mOrigDebugApp = debugApp;
10670            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10671            mAlwaysFinishActivities = alwaysFinishActivities;
10672            // This happens before any activities are started, so we can
10673            // change mConfiguration in-place.
10674            updateConfigurationLocked(configuration, null, false, true);
10675            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10676        }
10677    }
10678
10679    public boolean testIsSystemReady() {
10680        // no need to synchronize(this) just to read & return the value
10681        return mSystemReady;
10682    }
10683
10684    private static File getCalledPreBootReceiversFile() {
10685        File dataDir = Environment.getDataDirectory();
10686        File systemDir = new File(dataDir, "system");
10687        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10688        return fname;
10689    }
10690
10691    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10692        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10693        File file = getCalledPreBootReceiversFile();
10694        FileInputStream fis = null;
10695        try {
10696            fis = new FileInputStream(file);
10697            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10698            int fvers = dis.readInt();
10699            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10700                String vers = dis.readUTF();
10701                String codename = dis.readUTF();
10702                String build = dis.readUTF();
10703                if (android.os.Build.VERSION.RELEASE.equals(vers)
10704                        && android.os.Build.VERSION.CODENAME.equals(codename)
10705                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10706                    int num = dis.readInt();
10707                    while (num > 0) {
10708                        num--;
10709                        String pkg = dis.readUTF();
10710                        String cls = dis.readUTF();
10711                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10712                    }
10713                }
10714            }
10715        } catch (FileNotFoundException e) {
10716        } catch (IOException e) {
10717            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10718        } finally {
10719            if (fis != null) {
10720                try {
10721                    fis.close();
10722                } catch (IOException e) {
10723                }
10724            }
10725        }
10726        return lastDoneReceivers;
10727    }
10728
10729    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10730        File file = getCalledPreBootReceiversFile();
10731        FileOutputStream fos = null;
10732        DataOutputStream dos = null;
10733        try {
10734            fos = new FileOutputStream(file);
10735            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10736            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10737            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10738            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10739            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10740            dos.writeInt(list.size());
10741            for (int i=0; i<list.size(); i++) {
10742                dos.writeUTF(list.get(i).getPackageName());
10743                dos.writeUTF(list.get(i).getClassName());
10744            }
10745        } catch (IOException e) {
10746            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10747            file.delete();
10748        } finally {
10749            FileUtils.sync(fos);
10750            if (dos != null) {
10751                try {
10752                    dos.close();
10753                } catch (IOException e) {
10754                    // TODO Auto-generated catch block
10755                    e.printStackTrace();
10756                }
10757            }
10758        }
10759    }
10760
10761    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10762            ArrayList<ComponentName> doneReceivers, int userId) {
10763        boolean waitingUpdate = false;
10764        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10765        List<ResolveInfo> ris = null;
10766        try {
10767            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10768                    intent, null, 0, userId);
10769        } catch (RemoteException e) {
10770        }
10771        if (ris != null) {
10772            for (int i=ris.size()-1; i>=0; i--) {
10773                if ((ris.get(i).activityInfo.applicationInfo.flags
10774                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10775                    ris.remove(i);
10776                }
10777            }
10778            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10779
10780            // For User 0, load the version number. When delivering to a new user, deliver
10781            // to all receivers.
10782            if (userId == UserHandle.USER_OWNER) {
10783                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10784                for (int i=0; i<ris.size(); i++) {
10785                    ActivityInfo ai = ris.get(i).activityInfo;
10786                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10787                    if (lastDoneReceivers.contains(comp)) {
10788                        // We already did the pre boot receiver for this app with the current
10789                        // platform version, so don't do it again...
10790                        ris.remove(i);
10791                        i--;
10792                        // ...however, do keep it as one that has been done, so we don't
10793                        // forget about it when rewriting the file of last done receivers.
10794                        doneReceivers.add(comp);
10795                    }
10796                }
10797            }
10798
10799            // If primary user, send broadcast to all available users, else just to userId
10800            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10801                    : new int[] { userId };
10802            for (int i = 0; i < ris.size(); i++) {
10803                ActivityInfo ai = ris.get(i).activityInfo;
10804                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10805                doneReceivers.add(comp);
10806                intent.setComponent(comp);
10807                for (int j=0; j<users.length; j++) {
10808                    IIntentReceiver finisher = null;
10809                    // On last receiver and user, set up a completion callback
10810                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10811                        finisher = new IIntentReceiver.Stub() {
10812                            public void performReceive(Intent intent, int resultCode,
10813                                    String data, Bundle extras, boolean ordered,
10814                                    boolean sticky, int sendingUser) {
10815                                // The raw IIntentReceiver interface is called
10816                                // with the AM lock held, so redispatch to
10817                                // execute our code without the lock.
10818                                mHandler.post(onFinishCallback);
10819                            }
10820                        };
10821                    }
10822                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10823                            + " for user " + users[j]);
10824                    broadcastIntentLocked(null, null, intent, null, finisher,
10825                            0, null, null, null, AppOpsManager.OP_NONE,
10826                            true, false, MY_PID, Process.SYSTEM_UID,
10827                            users[j]);
10828                    if (finisher != null) {
10829                        waitingUpdate = true;
10830                    }
10831                }
10832            }
10833        }
10834
10835        return waitingUpdate;
10836    }
10837
10838    public void systemReady(final Runnable goingCallback) {
10839        synchronized(this) {
10840            if (mSystemReady) {
10841                // If we're done calling all the receivers, run the next "boot phase" passed in
10842                // by the SystemServer
10843                if (goingCallback != null) {
10844                    goingCallback.run();
10845                }
10846                return;
10847            }
10848
10849            // Make sure we have the current profile info, since it is needed for
10850            // security checks.
10851            updateCurrentProfileIdsLocked();
10852
10853            if (mRecentTasks == null) {
10854                mRecentTasks = mTaskPersister.restoreTasksLocked();
10855                if (!mRecentTasks.isEmpty()) {
10856                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10857                }
10858                cleanupRecentTasksLocked(UserHandle.USER_ALL);
10859                mTaskPersister.startPersisting();
10860            }
10861
10862            // Check to see if there are any update receivers to run.
10863            if (!mDidUpdate) {
10864                if (mWaitingUpdate) {
10865                    return;
10866                }
10867                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10868                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10869                    public void run() {
10870                        synchronized (ActivityManagerService.this) {
10871                            mDidUpdate = true;
10872                        }
10873                        writeLastDonePreBootReceivers(doneReceivers);
10874                        showBootMessage(mContext.getText(
10875                                R.string.android_upgrading_complete),
10876                                false);
10877                        systemReady(goingCallback);
10878                    }
10879                }, doneReceivers, UserHandle.USER_OWNER);
10880
10881                if (mWaitingUpdate) {
10882                    return;
10883                }
10884                mDidUpdate = true;
10885            }
10886
10887            mAppOpsService.systemReady();
10888            mSystemReady = true;
10889        }
10890
10891        ArrayList<ProcessRecord> procsToKill = null;
10892        synchronized(mPidsSelfLocked) {
10893            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10894                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10895                if (!isAllowedWhileBooting(proc.info)){
10896                    if (procsToKill == null) {
10897                        procsToKill = new ArrayList<ProcessRecord>();
10898                    }
10899                    procsToKill.add(proc);
10900                }
10901            }
10902        }
10903
10904        synchronized(this) {
10905            if (procsToKill != null) {
10906                for (int i=procsToKill.size()-1; i>=0; i--) {
10907                    ProcessRecord proc = procsToKill.get(i);
10908                    Slog.i(TAG, "Removing system update proc: " + proc);
10909                    removeProcessLocked(proc, true, false, "system update done");
10910                }
10911            }
10912
10913            // Now that we have cleaned up any update processes, we
10914            // are ready to start launching real processes and know that
10915            // we won't trample on them any more.
10916            mProcessesReady = true;
10917        }
10918
10919        Slog.i(TAG, "System now ready");
10920        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10921            SystemClock.uptimeMillis());
10922
10923        synchronized(this) {
10924            // Make sure we have no pre-ready processes sitting around.
10925
10926            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10927                ResolveInfo ri = mContext.getPackageManager()
10928                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10929                                STOCK_PM_FLAGS);
10930                CharSequence errorMsg = null;
10931                if (ri != null) {
10932                    ActivityInfo ai = ri.activityInfo;
10933                    ApplicationInfo app = ai.applicationInfo;
10934                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10935                        mTopAction = Intent.ACTION_FACTORY_TEST;
10936                        mTopData = null;
10937                        mTopComponent = new ComponentName(app.packageName,
10938                                ai.name);
10939                    } else {
10940                        errorMsg = mContext.getResources().getText(
10941                                com.android.internal.R.string.factorytest_not_system);
10942                    }
10943                } else {
10944                    errorMsg = mContext.getResources().getText(
10945                            com.android.internal.R.string.factorytest_no_action);
10946                }
10947                if (errorMsg != null) {
10948                    mTopAction = null;
10949                    mTopData = null;
10950                    mTopComponent = null;
10951                    Message msg = Message.obtain();
10952                    msg.what = SHOW_FACTORY_ERROR_MSG;
10953                    msg.getData().putCharSequence("msg", errorMsg);
10954                    mHandler.sendMessage(msg);
10955                }
10956            }
10957        }
10958
10959        retrieveSettings();
10960
10961        synchronized (this) {
10962            readGrantedUriPermissionsLocked();
10963        }
10964
10965        if (goingCallback != null) goingCallback.run();
10966
10967        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
10968                Integer.toString(mCurrentUserId), mCurrentUserId);
10969        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
10970                Integer.toString(mCurrentUserId), mCurrentUserId);
10971        mSystemServiceManager.startUser(mCurrentUserId);
10972
10973        synchronized (this) {
10974            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10975                try {
10976                    List apps = AppGlobals.getPackageManager().
10977                        getPersistentApplications(STOCK_PM_FLAGS);
10978                    if (apps != null) {
10979                        int N = apps.size();
10980                        int i;
10981                        for (i=0; i<N; i++) {
10982                            ApplicationInfo info
10983                                = (ApplicationInfo)apps.get(i);
10984                            if (info != null &&
10985                                    !info.packageName.equals("android")) {
10986                                addAppLocked(info, false, null /* ABI override */);
10987                            }
10988                        }
10989                    }
10990                } catch (RemoteException ex) {
10991                    // pm is in same process, this will never happen.
10992                }
10993            }
10994
10995            // Start up initial activity.
10996            mBooting = true;
10997
10998            try {
10999                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11000                    Message msg = Message.obtain();
11001                    msg.what = SHOW_UID_ERROR_MSG;
11002                    mHandler.sendMessage(msg);
11003                }
11004            } catch (RemoteException e) {
11005            }
11006
11007            long ident = Binder.clearCallingIdentity();
11008            try {
11009                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11010                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11011                        | Intent.FLAG_RECEIVER_FOREGROUND);
11012                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11013                broadcastIntentLocked(null, null, intent,
11014                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11015                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11016                intent = new Intent(Intent.ACTION_USER_STARTING);
11017                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11018                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11019                broadcastIntentLocked(null, null, intent,
11020                        null, new IIntentReceiver.Stub() {
11021                            @Override
11022                            public void performReceive(Intent intent, int resultCode, String data,
11023                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11024                                    throws RemoteException {
11025                            }
11026                        }, 0, null, null,
11027                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11028                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11029            } catch (Throwable t) {
11030                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11031            } finally {
11032                Binder.restoreCallingIdentity(ident);
11033            }
11034            mStackSupervisor.resumeTopActivitiesLocked();
11035            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11036        }
11037    }
11038
11039    private boolean makeAppCrashingLocked(ProcessRecord app,
11040            String shortMsg, String longMsg, String stackTrace) {
11041        app.crashing = true;
11042        app.crashingReport = generateProcessError(app,
11043                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11044        startAppProblemLocked(app);
11045        app.stopFreezingAllLocked();
11046        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11047    }
11048
11049    private void makeAppNotRespondingLocked(ProcessRecord app,
11050            String activity, String shortMsg, String longMsg) {
11051        app.notResponding = true;
11052        app.notRespondingReport = generateProcessError(app,
11053                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11054                activity, shortMsg, longMsg, null);
11055        startAppProblemLocked(app);
11056        app.stopFreezingAllLocked();
11057    }
11058
11059    /**
11060     * Generate a process error record, suitable for attachment to a ProcessRecord.
11061     *
11062     * @param app The ProcessRecord in which the error occurred.
11063     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11064     *                      ActivityManager.AppErrorStateInfo
11065     * @param activity The activity associated with the crash, if known.
11066     * @param shortMsg Short message describing the crash.
11067     * @param longMsg Long message describing the crash.
11068     * @param stackTrace Full crash stack trace, may be null.
11069     *
11070     * @return Returns a fully-formed AppErrorStateInfo record.
11071     */
11072    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11073            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11074        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11075
11076        report.condition = condition;
11077        report.processName = app.processName;
11078        report.pid = app.pid;
11079        report.uid = app.info.uid;
11080        report.tag = activity;
11081        report.shortMsg = shortMsg;
11082        report.longMsg = longMsg;
11083        report.stackTrace = stackTrace;
11084
11085        return report;
11086    }
11087
11088    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11089        synchronized (this) {
11090            app.crashing = false;
11091            app.crashingReport = null;
11092            app.notResponding = false;
11093            app.notRespondingReport = null;
11094            if (app.anrDialog == fromDialog) {
11095                app.anrDialog = null;
11096            }
11097            if (app.waitDialog == fromDialog) {
11098                app.waitDialog = null;
11099            }
11100            if (app.pid > 0 && app.pid != MY_PID) {
11101                handleAppCrashLocked(app, null, null, null);
11102                app.kill("user request after error", true);
11103            }
11104        }
11105    }
11106
11107    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11108            String stackTrace) {
11109        long now = SystemClock.uptimeMillis();
11110
11111        Long crashTime;
11112        if (!app.isolated) {
11113            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11114        } else {
11115            crashTime = null;
11116        }
11117        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11118            // This process loses!
11119            Slog.w(TAG, "Process " + app.info.processName
11120                    + " has crashed too many times: killing!");
11121            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11122                    app.userId, app.info.processName, app.uid);
11123            mStackSupervisor.handleAppCrashLocked(app);
11124            if (!app.persistent) {
11125                // We don't want to start this process again until the user
11126                // explicitly does so...  but for persistent process, we really
11127                // need to keep it running.  If a persistent process is actually
11128                // repeatedly crashing, then badness for everyone.
11129                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11130                        app.info.processName);
11131                if (!app.isolated) {
11132                    // XXX We don't have a way to mark isolated processes
11133                    // as bad, since they don't have a peristent identity.
11134                    mBadProcesses.put(app.info.processName, app.uid,
11135                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11136                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11137                }
11138                app.bad = true;
11139                app.removed = true;
11140                // Don't let services in this process be restarted and potentially
11141                // annoy the user repeatedly.  Unless it is persistent, since those
11142                // processes run critical code.
11143                removeProcessLocked(app, false, false, "crash");
11144                mStackSupervisor.resumeTopActivitiesLocked();
11145                return false;
11146            }
11147            mStackSupervisor.resumeTopActivitiesLocked();
11148        } else {
11149            mStackSupervisor.finishTopRunningActivityLocked(app);
11150        }
11151
11152        // Bump up the crash count of any services currently running in the proc.
11153        for (int i=app.services.size()-1; i>=0; i--) {
11154            // Any services running in the application need to be placed
11155            // back in the pending list.
11156            ServiceRecord sr = app.services.valueAt(i);
11157            sr.crashCount++;
11158        }
11159
11160        // If the crashing process is what we consider to be the "home process" and it has been
11161        // replaced by a third-party app, clear the package preferred activities from packages
11162        // with a home activity running in the process to prevent a repeatedly crashing app
11163        // from blocking the user to manually clear the list.
11164        final ArrayList<ActivityRecord> activities = app.activities;
11165        if (app == mHomeProcess && activities.size() > 0
11166                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11167            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11168                final ActivityRecord r = activities.get(activityNdx);
11169                if (r.isHomeActivity()) {
11170                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11171                    try {
11172                        ActivityThread.getPackageManager()
11173                                .clearPackagePreferredActivities(r.packageName);
11174                    } catch (RemoteException c) {
11175                        // pm is in same process, this will never happen.
11176                    }
11177                }
11178            }
11179        }
11180
11181        if (!app.isolated) {
11182            // XXX Can't keep track of crash times for isolated processes,
11183            // because they don't have a perisistent identity.
11184            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11185        }
11186
11187        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11188        return true;
11189    }
11190
11191    void startAppProblemLocked(ProcessRecord app) {
11192        // If this app is not running under the current user, then we
11193        // can't give it a report button because that would require
11194        // launching the report UI under a different user.
11195        app.errorReportReceiver = null;
11196
11197        for (int userId : mCurrentProfileIds) {
11198            if (app.userId == userId) {
11199                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11200                        mContext, app.info.packageName, app.info.flags);
11201            }
11202        }
11203        skipCurrentReceiverLocked(app);
11204    }
11205
11206    void skipCurrentReceiverLocked(ProcessRecord app) {
11207        for (BroadcastQueue queue : mBroadcastQueues) {
11208            queue.skipCurrentReceiverLocked(app);
11209        }
11210    }
11211
11212    /**
11213     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11214     * The application process will exit immediately after this call returns.
11215     * @param app object of the crashing app, null for the system server
11216     * @param crashInfo describing the exception
11217     */
11218    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11219        ProcessRecord r = findAppProcess(app, "Crash");
11220        final String processName = app == null ? "system_server"
11221                : (r == null ? "unknown" : r.processName);
11222
11223        handleApplicationCrashInner("crash", r, processName, crashInfo);
11224    }
11225
11226    /* Native crash reporting uses this inner version because it needs to be somewhat
11227     * decoupled from the AM-managed cleanup lifecycle
11228     */
11229    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11230            ApplicationErrorReport.CrashInfo crashInfo) {
11231        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11232                UserHandle.getUserId(Binder.getCallingUid()), processName,
11233                r == null ? -1 : r.info.flags,
11234                crashInfo.exceptionClassName,
11235                crashInfo.exceptionMessage,
11236                crashInfo.throwFileName,
11237                crashInfo.throwLineNumber);
11238
11239        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11240
11241        crashApplication(r, crashInfo);
11242    }
11243
11244    public void handleApplicationStrictModeViolation(
11245            IBinder app,
11246            int violationMask,
11247            StrictMode.ViolationInfo info) {
11248        ProcessRecord r = findAppProcess(app, "StrictMode");
11249        if (r == null) {
11250            return;
11251        }
11252
11253        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11254            Integer stackFingerprint = info.hashCode();
11255            boolean logIt = true;
11256            synchronized (mAlreadyLoggedViolatedStacks) {
11257                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11258                    logIt = false;
11259                    // TODO: sub-sample into EventLog for these, with
11260                    // the info.durationMillis?  Then we'd get
11261                    // the relative pain numbers, without logging all
11262                    // the stack traces repeatedly.  We'd want to do
11263                    // likewise in the client code, which also does
11264                    // dup suppression, before the Binder call.
11265                } else {
11266                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11267                        mAlreadyLoggedViolatedStacks.clear();
11268                    }
11269                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11270                }
11271            }
11272            if (logIt) {
11273                logStrictModeViolationToDropBox(r, info);
11274            }
11275        }
11276
11277        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11278            AppErrorResult result = new AppErrorResult();
11279            synchronized (this) {
11280                final long origId = Binder.clearCallingIdentity();
11281
11282                Message msg = Message.obtain();
11283                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11284                HashMap<String, Object> data = new HashMap<String, Object>();
11285                data.put("result", result);
11286                data.put("app", r);
11287                data.put("violationMask", violationMask);
11288                data.put("info", info);
11289                msg.obj = data;
11290                mHandler.sendMessage(msg);
11291
11292                Binder.restoreCallingIdentity(origId);
11293            }
11294            int res = result.get();
11295            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11296        }
11297    }
11298
11299    // Depending on the policy in effect, there could be a bunch of
11300    // these in quick succession so we try to batch these together to
11301    // minimize disk writes, number of dropbox entries, and maximize
11302    // compression, by having more fewer, larger records.
11303    private void logStrictModeViolationToDropBox(
11304            ProcessRecord process,
11305            StrictMode.ViolationInfo info) {
11306        if (info == null) {
11307            return;
11308        }
11309        final boolean isSystemApp = process == null ||
11310                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11311                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11312        final String processName = process == null ? "unknown" : process.processName;
11313        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11314        final DropBoxManager dbox = (DropBoxManager)
11315                mContext.getSystemService(Context.DROPBOX_SERVICE);
11316
11317        // Exit early if the dropbox isn't configured to accept this report type.
11318        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11319
11320        boolean bufferWasEmpty;
11321        boolean needsFlush;
11322        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11323        synchronized (sb) {
11324            bufferWasEmpty = sb.length() == 0;
11325            appendDropBoxProcessHeaders(process, processName, sb);
11326            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11327            sb.append("System-App: ").append(isSystemApp).append("\n");
11328            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11329            if (info.violationNumThisLoop != 0) {
11330                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11331            }
11332            if (info.numAnimationsRunning != 0) {
11333                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11334            }
11335            if (info.broadcastIntentAction != null) {
11336                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11337            }
11338            if (info.durationMillis != -1) {
11339                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11340            }
11341            if (info.numInstances != -1) {
11342                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11343            }
11344            if (info.tags != null) {
11345                for (String tag : info.tags) {
11346                    sb.append("Span-Tag: ").append(tag).append("\n");
11347                }
11348            }
11349            sb.append("\n");
11350            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11351                sb.append(info.crashInfo.stackTrace);
11352            }
11353            sb.append("\n");
11354
11355            // Only buffer up to ~64k.  Various logging bits truncate
11356            // things at 128k.
11357            needsFlush = (sb.length() > 64 * 1024);
11358        }
11359
11360        // Flush immediately if the buffer's grown too large, or this
11361        // is a non-system app.  Non-system apps are isolated with a
11362        // different tag & policy and not batched.
11363        //
11364        // Batching is useful during internal testing with
11365        // StrictMode settings turned up high.  Without batching,
11366        // thousands of separate files could be created on boot.
11367        if (!isSystemApp || needsFlush) {
11368            new Thread("Error dump: " + dropboxTag) {
11369                @Override
11370                public void run() {
11371                    String report;
11372                    synchronized (sb) {
11373                        report = sb.toString();
11374                        sb.delete(0, sb.length());
11375                        sb.trimToSize();
11376                    }
11377                    if (report.length() != 0) {
11378                        dbox.addText(dropboxTag, report);
11379                    }
11380                }
11381            }.start();
11382            return;
11383        }
11384
11385        // System app batching:
11386        if (!bufferWasEmpty) {
11387            // An existing dropbox-writing thread is outstanding, so
11388            // we don't need to start it up.  The existing thread will
11389            // catch the buffer appends we just did.
11390            return;
11391        }
11392
11393        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11394        // (After this point, we shouldn't access AMS internal data structures.)
11395        new Thread("Error dump: " + dropboxTag) {
11396            @Override
11397            public void run() {
11398                // 5 second sleep to let stacks arrive and be batched together
11399                try {
11400                    Thread.sleep(5000);  // 5 seconds
11401                } catch (InterruptedException e) {}
11402
11403                String errorReport;
11404                synchronized (mStrictModeBuffer) {
11405                    errorReport = mStrictModeBuffer.toString();
11406                    if (errorReport.length() == 0) {
11407                        return;
11408                    }
11409                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11410                    mStrictModeBuffer.trimToSize();
11411                }
11412                dbox.addText(dropboxTag, errorReport);
11413            }
11414        }.start();
11415    }
11416
11417    /**
11418     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11419     * @param app object of the crashing app, null for the system server
11420     * @param tag reported by the caller
11421     * @param crashInfo describing the context of the error
11422     * @return true if the process should exit immediately (WTF is fatal)
11423     */
11424    public boolean handleApplicationWtf(IBinder app, String tag,
11425            ApplicationErrorReport.CrashInfo crashInfo) {
11426        ProcessRecord r = findAppProcess(app, "WTF");
11427        final String processName = app == null ? "system_server"
11428                : (r == null ? "unknown" : r.processName);
11429
11430        EventLog.writeEvent(EventLogTags.AM_WTF,
11431                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
11432                processName,
11433                r == null ? -1 : r.info.flags,
11434                tag, crashInfo.exceptionMessage);
11435
11436        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11437
11438        if (r != null && r.pid != Process.myPid() &&
11439                Settings.Global.getInt(mContext.getContentResolver(),
11440                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11441            crashApplication(r, crashInfo);
11442            return true;
11443        } else {
11444            return false;
11445        }
11446    }
11447
11448    /**
11449     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11450     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11451     */
11452    private ProcessRecord findAppProcess(IBinder app, String reason) {
11453        if (app == null) {
11454            return null;
11455        }
11456
11457        synchronized (this) {
11458            final int NP = mProcessNames.getMap().size();
11459            for (int ip=0; ip<NP; ip++) {
11460                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11461                final int NA = apps.size();
11462                for (int ia=0; ia<NA; ia++) {
11463                    ProcessRecord p = apps.valueAt(ia);
11464                    if (p.thread != null && p.thread.asBinder() == app) {
11465                        return p;
11466                    }
11467                }
11468            }
11469
11470            Slog.w(TAG, "Can't find mystery application for " + reason
11471                    + " from pid=" + Binder.getCallingPid()
11472                    + " uid=" + Binder.getCallingUid() + ": " + app);
11473            return null;
11474        }
11475    }
11476
11477    /**
11478     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11479     * to append various headers to the dropbox log text.
11480     */
11481    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11482            StringBuilder sb) {
11483        // Watchdog thread ends up invoking this function (with
11484        // a null ProcessRecord) to add the stack file to dropbox.
11485        // Do not acquire a lock on this (am) in such cases, as it
11486        // could cause a potential deadlock, if and when watchdog
11487        // is invoked due to unavailability of lock on am and it
11488        // would prevent watchdog from killing system_server.
11489        if (process == null) {
11490            sb.append("Process: ").append(processName).append("\n");
11491            return;
11492        }
11493        // Note: ProcessRecord 'process' is guarded by the service
11494        // instance.  (notably process.pkgList, which could otherwise change
11495        // concurrently during execution of this method)
11496        synchronized (this) {
11497            sb.append("Process: ").append(processName).append("\n");
11498            int flags = process.info.flags;
11499            IPackageManager pm = AppGlobals.getPackageManager();
11500            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11501            for (int ip=0; ip<process.pkgList.size(); ip++) {
11502                String pkg = process.pkgList.keyAt(ip);
11503                sb.append("Package: ").append(pkg);
11504                try {
11505                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11506                    if (pi != null) {
11507                        sb.append(" v").append(pi.versionCode);
11508                        if (pi.versionName != null) {
11509                            sb.append(" (").append(pi.versionName).append(")");
11510                        }
11511                    }
11512                } catch (RemoteException e) {
11513                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11514                }
11515                sb.append("\n");
11516            }
11517        }
11518    }
11519
11520    private static String processClass(ProcessRecord process) {
11521        if (process == null || process.pid == MY_PID) {
11522            return "system_server";
11523        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11524            return "system_app";
11525        } else {
11526            return "data_app";
11527        }
11528    }
11529
11530    /**
11531     * Write a description of an error (crash, WTF, ANR) to the drop box.
11532     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11533     * @param process which caused the error, null means the system server
11534     * @param activity which triggered the error, null if unknown
11535     * @param parent activity related to the error, null if unknown
11536     * @param subject line related to the error, null if absent
11537     * @param report in long form describing the error, null if absent
11538     * @param logFile to include in the report, null if none
11539     * @param crashInfo giving an application stack trace, null if absent
11540     */
11541    public void addErrorToDropBox(String eventType,
11542            ProcessRecord process, String processName, ActivityRecord activity,
11543            ActivityRecord parent, String subject,
11544            final String report, final File logFile,
11545            final ApplicationErrorReport.CrashInfo crashInfo) {
11546        // NOTE -- this must never acquire the ActivityManagerService lock,
11547        // otherwise the watchdog may be prevented from resetting the system.
11548
11549        final String dropboxTag = processClass(process) + "_" + eventType;
11550        final DropBoxManager dbox = (DropBoxManager)
11551                mContext.getSystemService(Context.DROPBOX_SERVICE);
11552
11553        // Exit early if the dropbox isn't configured to accept this report type.
11554        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11555
11556        final StringBuilder sb = new StringBuilder(1024);
11557        appendDropBoxProcessHeaders(process, processName, sb);
11558        if (activity != null) {
11559            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11560        }
11561        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11562            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11563        }
11564        if (parent != null && parent != activity) {
11565            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11566        }
11567        if (subject != null) {
11568            sb.append("Subject: ").append(subject).append("\n");
11569        }
11570        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11571        if (Debug.isDebuggerConnected()) {
11572            sb.append("Debugger: Connected\n");
11573        }
11574        sb.append("\n");
11575
11576        // Do the rest in a worker thread to avoid blocking the caller on I/O
11577        // (After this point, we shouldn't access AMS internal data structures.)
11578        Thread worker = new Thread("Error dump: " + dropboxTag) {
11579            @Override
11580            public void run() {
11581                if (report != null) {
11582                    sb.append(report);
11583                }
11584                if (logFile != null) {
11585                    try {
11586                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11587                                    "\n\n[[TRUNCATED]]"));
11588                    } catch (IOException e) {
11589                        Slog.e(TAG, "Error reading " + logFile, e);
11590                    }
11591                }
11592                if (crashInfo != null && crashInfo.stackTrace != null) {
11593                    sb.append(crashInfo.stackTrace);
11594                }
11595
11596                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11597                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11598                if (lines > 0) {
11599                    sb.append("\n");
11600
11601                    // Merge several logcat streams, and take the last N lines
11602                    InputStreamReader input = null;
11603                    try {
11604                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11605                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11606                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11607
11608                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11609                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11610                        input = new InputStreamReader(logcat.getInputStream());
11611
11612                        int num;
11613                        char[] buf = new char[8192];
11614                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11615                    } catch (IOException e) {
11616                        Slog.e(TAG, "Error running logcat", e);
11617                    } finally {
11618                        if (input != null) try { input.close(); } catch (IOException e) {}
11619                    }
11620                }
11621
11622                dbox.addText(dropboxTag, sb.toString());
11623            }
11624        };
11625
11626        if (process == null) {
11627            // If process is null, we are being called from some internal code
11628            // and may be about to die -- run this synchronously.
11629            worker.run();
11630        } else {
11631            worker.start();
11632        }
11633    }
11634
11635    /**
11636     * Bring up the "unexpected error" dialog box for a crashing app.
11637     * Deal with edge cases (intercepts from instrumented applications,
11638     * ActivityController, error intent receivers, that sort of thing).
11639     * @param r the application crashing
11640     * @param crashInfo describing the failure
11641     */
11642    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11643        long timeMillis = System.currentTimeMillis();
11644        String shortMsg = crashInfo.exceptionClassName;
11645        String longMsg = crashInfo.exceptionMessage;
11646        String stackTrace = crashInfo.stackTrace;
11647        if (shortMsg != null && longMsg != null) {
11648            longMsg = shortMsg + ": " + longMsg;
11649        } else if (shortMsg != null) {
11650            longMsg = shortMsg;
11651        }
11652
11653        AppErrorResult result = new AppErrorResult();
11654        synchronized (this) {
11655            if (mController != null) {
11656                try {
11657                    String name = r != null ? r.processName : null;
11658                    int pid = r != null ? r.pid : Binder.getCallingPid();
11659                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11660                    if (!mController.appCrashed(name, pid,
11661                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11662                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11663                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11664                            Slog.w(TAG, "Skip killing native crashed app " + name
11665                                    + "(" + pid + ") during testing");
11666                        } else {
11667                            Slog.w(TAG, "Force-killing crashed app " + name
11668                                    + " at watcher's request");
11669                            if (r != null) {
11670                                r.kill("crash", true);
11671                            } else {
11672                                // Huh.
11673                                Process.killProcess(pid);
11674                                Process.killProcessGroup(uid, pid);
11675                            }
11676                        }
11677                        return;
11678                    }
11679                } catch (RemoteException e) {
11680                    mController = null;
11681                    Watchdog.getInstance().setActivityController(null);
11682                }
11683            }
11684
11685            final long origId = Binder.clearCallingIdentity();
11686
11687            // If this process is running instrumentation, finish it.
11688            if (r != null && r.instrumentationClass != null) {
11689                Slog.w(TAG, "Error in app " + r.processName
11690                      + " running instrumentation " + r.instrumentationClass + ":");
11691                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11692                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11693                Bundle info = new Bundle();
11694                info.putString("shortMsg", shortMsg);
11695                info.putString("longMsg", longMsg);
11696                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11697                Binder.restoreCallingIdentity(origId);
11698                return;
11699            }
11700
11701            // If we can't identify the process or it's already exceeded its crash quota,
11702            // quit right away without showing a crash dialog.
11703            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11704                Binder.restoreCallingIdentity(origId);
11705                return;
11706            }
11707
11708            Message msg = Message.obtain();
11709            msg.what = SHOW_ERROR_MSG;
11710            HashMap data = new HashMap();
11711            data.put("result", result);
11712            data.put("app", r);
11713            msg.obj = data;
11714            mHandler.sendMessage(msg);
11715
11716            Binder.restoreCallingIdentity(origId);
11717        }
11718
11719        int res = result.get();
11720
11721        Intent appErrorIntent = null;
11722        synchronized (this) {
11723            if (r != null && !r.isolated) {
11724                // XXX Can't keep track of crash time for isolated processes,
11725                // since they don't have a persistent identity.
11726                mProcessCrashTimes.put(r.info.processName, r.uid,
11727                        SystemClock.uptimeMillis());
11728            }
11729            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11730                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11731            }
11732        }
11733
11734        if (appErrorIntent != null) {
11735            try {
11736                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11737            } catch (ActivityNotFoundException e) {
11738                Slog.w(TAG, "bug report receiver dissappeared", e);
11739            }
11740        }
11741    }
11742
11743    Intent createAppErrorIntentLocked(ProcessRecord r,
11744            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11745        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11746        if (report == null) {
11747            return null;
11748        }
11749        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11750        result.setComponent(r.errorReportReceiver);
11751        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11752        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11753        return result;
11754    }
11755
11756    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11757            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11758        if (r.errorReportReceiver == null) {
11759            return null;
11760        }
11761
11762        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11763            return null;
11764        }
11765
11766        ApplicationErrorReport report = new ApplicationErrorReport();
11767        report.packageName = r.info.packageName;
11768        report.installerPackageName = r.errorReportReceiver.getPackageName();
11769        report.processName = r.processName;
11770        report.time = timeMillis;
11771        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11772
11773        if (r.crashing || r.forceCrashReport) {
11774            report.type = ApplicationErrorReport.TYPE_CRASH;
11775            report.crashInfo = crashInfo;
11776        } else if (r.notResponding) {
11777            report.type = ApplicationErrorReport.TYPE_ANR;
11778            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11779
11780            report.anrInfo.activity = r.notRespondingReport.tag;
11781            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11782            report.anrInfo.info = r.notRespondingReport.longMsg;
11783        }
11784
11785        return report;
11786    }
11787
11788    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11789        enforceNotIsolatedCaller("getProcessesInErrorState");
11790        // assume our apps are happy - lazy create the list
11791        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11792
11793        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11794                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11795        int userId = UserHandle.getUserId(Binder.getCallingUid());
11796
11797        synchronized (this) {
11798
11799            // iterate across all processes
11800            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11801                ProcessRecord app = mLruProcesses.get(i);
11802                if (!allUsers && app.userId != userId) {
11803                    continue;
11804                }
11805                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11806                    // This one's in trouble, so we'll generate a report for it
11807                    // crashes are higher priority (in case there's a crash *and* an anr)
11808                    ActivityManager.ProcessErrorStateInfo report = null;
11809                    if (app.crashing) {
11810                        report = app.crashingReport;
11811                    } else if (app.notResponding) {
11812                        report = app.notRespondingReport;
11813                    }
11814
11815                    if (report != null) {
11816                        if (errList == null) {
11817                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11818                        }
11819                        errList.add(report);
11820                    } else {
11821                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11822                                " crashing = " + app.crashing +
11823                                " notResponding = " + app.notResponding);
11824                    }
11825                }
11826            }
11827        }
11828
11829        return errList;
11830    }
11831
11832    static int procStateToImportance(int procState, int memAdj,
11833            ActivityManager.RunningAppProcessInfo currApp) {
11834        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11835        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11836            currApp.lru = memAdj;
11837        } else {
11838            currApp.lru = 0;
11839        }
11840        return imp;
11841    }
11842
11843    private void fillInProcMemInfo(ProcessRecord app,
11844            ActivityManager.RunningAppProcessInfo outInfo) {
11845        outInfo.pid = app.pid;
11846        outInfo.uid = app.info.uid;
11847        if (mHeavyWeightProcess == app) {
11848            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11849        }
11850        if (app.persistent) {
11851            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11852        }
11853        if (app.activities.size() > 0) {
11854            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11855        }
11856        outInfo.lastTrimLevel = app.trimMemoryLevel;
11857        int adj = app.curAdj;
11858        int procState = app.curProcState;
11859        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11860        outInfo.importanceReasonCode = app.adjTypeCode;
11861        outInfo.processState = app.curProcState;
11862    }
11863
11864    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11865        enforceNotIsolatedCaller("getRunningAppProcesses");
11866        // Lazy instantiation of list
11867        List<ActivityManager.RunningAppProcessInfo> runList = null;
11868        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11869                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11870        int userId = UserHandle.getUserId(Binder.getCallingUid());
11871        synchronized (this) {
11872            // Iterate across all processes
11873            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11874                ProcessRecord app = mLruProcesses.get(i);
11875                if (!allUsers && app.userId != userId) {
11876                    continue;
11877                }
11878                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11879                    // Generate process state info for running application
11880                    ActivityManager.RunningAppProcessInfo currApp =
11881                        new ActivityManager.RunningAppProcessInfo(app.processName,
11882                                app.pid, app.getPackageList());
11883                    fillInProcMemInfo(app, currApp);
11884                    if (app.adjSource instanceof ProcessRecord) {
11885                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11886                        currApp.importanceReasonImportance =
11887                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
11888                                        app.adjSourceProcState);
11889                    } else if (app.adjSource instanceof ActivityRecord) {
11890                        ActivityRecord r = (ActivityRecord)app.adjSource;
11891                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11892                    }
11893                    if (app.adjTarget instanceof ComponentName) {
11894                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11895                    }
11896                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11897                    //        + " lru=" + currApp.lru);
11898                    if (runList == null) {
11899                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11900                    }
11901                    runList.add(currApp);
11902                }
11903            }
11904        }
11905        return runList;
11906    }
11907
11908    public List<ApplicationInfo> getRunningExternalApplications() {
11909        enforceNotIsolatedCaller("getRunningExternalApplications");
11910        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11911        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11912        if (runningApps != null && runningApps.size() > 0) {
11913            Set<String> extList = new HashSet<String>();
11914            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11915                if (app.pkgList != null) {
11916                    for (String pkg : app.pkgList) {
11917                        extList.add(pkg);
11918                    }
11919                }
11920            }
11921            IPackageManager pm = AppGlobals.getPackageManager();
11922            for (String pkg : extList) {
11923                try {
11924                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11925                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11926                        retList.add(info);
11927                    }
11928                } catch (RemoteException e) {
11929                }
11930            }
11931        }
11932        return retList;
11933    }
11934
11935    @Override
11936    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
11937        enforceNotIsolatedCaller("getMyMemoryState");
11938        synchronized (this) {
11939            ProcessRecord proc;
11940            synchronized (mPidsSelfLocked) {
11941                proc = mPidsSelfLocked.get(Binder.getCallingPid());
11942            }
11943            fillInProcMemInfo(proc, outInfo);
11944        }
11945    }
11946
11947    @Override
11948    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11949        if (checkCallingPermission(android.Manifest.permission.DUMP)
11950                != PackageManager.PERMISSION_GRANTED) {
11951            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11952                    + Binder.getCallingPid()
11953                    + ", uid=" + Binder.getCallingUid()
11954                    + " without permission "
11955                    + android.Manifest.permission.DUMP);
11956            return;
11957        }
11958
11959        boolean dumpAll = false;
11960        boolean dumpClient = false;
11961        String dumpPackage = null;
11962
11963        int opti = 0;
11964        while (opti < args.length) {
11965            String opt = args[opti];
11966            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11967                break;
11968            }
11969            opti++;
11970            if ("-a".equals(opt)) {
11971                dumpAll = true;
11972            } else if ("-c".equals(opt)) {
11973                dumpClient = true;
11974            } else if ("-h".equals(opt)) {
11975                pw.println("Activity manager dump options:");
11976                pw.println("  [-a] [-c] [-h] [cmd] ...");
11977                pw.println("  cmd may be one of:");
11978                pw.println("    a[ctivities]: activity stack state");
11979                pw.println("    r[recents]: recent activities state");
11980                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11981                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11982                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11983                pw.println("    o[om]: out of memory management");
11984                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11985                pw.println("    provider [COMP_SPEC]: provider client-side state");
11986                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11987                pw.println("    service [COMP_SPEC]: service client-side state");
11988                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11989                pw.println("    all: dump all activities");
11990                pw.println("    top: dump the top activity");
11991                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11992                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11993                pw.println("    a partial substring in a component name, a");
11994                pw.println("    hex object identifier.");
11995                pw.println("  -a: include all available server state.");
11996                pw.println("  -c: include client state.");
11997                return;
11998            } else {
11999                pw.println("Unknown argument: " + opt + "; use -h for help");
12000            }
12001        }
12002
12003        long origId = Binder.clearCallingIdentity();
12004        boolean more = false;
12005        // Is the caller requesting to dump a particular piece of data?
12006        if (opti < args.length) {
12007            String cmd = args[opti];
12008            opti++;
12009            if ("activities".equals(cmd) || "a".equals(cmd)) {
12010                synchronized (this) {
12011                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12012                }
12013            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12014                synchronized (this) {
12015                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12016                }
12017            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12018                String[] newArgs;
12019                String name;
12020                if (opti >= args.length) {
12021                    name = null;
12022                    newArgs = EMPTY_STRING_ARRAY;
12023                } else {
12024                    name = args[opti];
12025                    opti++;
12026                    newArgs = new String[args.length - opti];
12027                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12028                            args.length - opti);
12029                }
12030                synchronized (this) {
12031                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12032                }
12033            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12034                String[] newArgs;
12035                String name;
12036                if (opti >= args.length) {
12037                    name = null;
12038                    newArgs = EMPTY_STRING_ARRAY;
12039                } else {
12040                    name = args[opti];
12041                    opti++;
12042                    newArgs = new String[args.length - opti];
12043                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12044                            args.length - opti);
12045                }
12046                synchronized (this) {
12047                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12048                }
12049            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12050                String[] newArgs;
12051                String name;
12052                if (opti >= args.length) {
12053                    name = null;
12054                    newArgs = EMPTY_STRING_ARRAY;
12055                } else {
12056                    name = args[opti];
12057                    opti++;
12058                    newArgs = new String[args.length - opti];
12059                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12060                            args.length - opti);
12061                }
12062                synchronized (this) {
12063                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12064                }
12065            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12066                synchronized (this) {
12067                    dumpOomLocked(fd, pw, args, opti, true);
12068                }
12069            } else if ("provider".equals(cmd)) {
12070                String[] newArgs;
12071                String name;
12072                if (opti >= args.length) {
12073                    name = null;
12074                    newArgs = EMPTY_STRING_ARRAY;
12075                } else {
12076                    name = args[opti];
12077                    opti++;
12078                    newArgs = new String[args.length - opti];
12079                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12080                }
12081                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12082                    pw.println("No providers match: " + name);
12083                    pw.println("Use -h for help.");
12084                }
12085            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12086                synchronized (this) {
12087                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12088                }
12089            } else if ("service".equals(cmd)) {
12090                String[] newArgs;
12091                String name;
12092                if (opti >= args.length) {
12093                    name = null;
12094                    newArgs = EMPTY_STRING_ARRAY;
12095                } else {
12096                    name = args[opti];
12097                    opti++;
12098                    newArgs = new String[args.length - opti];
12099                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12100                            args.length - opti);
12101                }
12102                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12103                    pw.println("No services match: " + name);
12104                    pw.println("Use -h for help.");
12105                }
12106            } else if ("package".equals(cmd)) {
12107                String[] newArgs;
12108                if (opti >= args.length) {
12109                    pw.println("package: no package name specified");
12110                    pw.println("Use -h for help.");
12111                } else {
12112                    dumpPackage = args[opti];
12113                    opti++;
12114                    newArgs = new String[args.length - opti];
12115                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12116                            args.length - opti);
12117                    args = newArgs;
12118                    opti = 0;
12119                    more = true;
12120                }
12121            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12122                synchronized (this) {
12123                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12124                }
12125            } else {
12126                // Dumping a single activity?
12127                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12128                    pw.println("Bad activity command, or no activities match: " + cmd);
12129                    pw.println("Use -h for help.");
12130                }
12131            }
12132            if (!more) {
12133                Binder.restoreCallingIdentity(origId);
12134                return;
12135            }
12136        }
12137
12138        // No piece of data specified, dump everything.
12139        synchronized (this) {
12140            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12141            pw.println();
12142            if (dumpAll) {
12143                pw.println("-------------------------------------------------------------------------------");
12144            }
12145            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12146            pw.println();
12147            if (dumpAll) {
12148                pw.println("-------------------------------------------------------------------------------");
12149            }
12150            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12151            pw.println();
12152            if (dumpAll) {
12153                pw.println("-------------------------------------------------------------------------------");
12154            }
12155            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12156            pw.println();
12157            if (dumpAll) {
12158                pw.println("-------------------------------------------------------------------------------");
12159            }
12160            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12161            pw.println();
12162            if (dumpAll) {
12163                pw.println("-------------------------------------------------------------------------------");
12164            }
12165            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12166            pw.println();
12167            if (dumpAll) {
12168                pw.println("-------------------------------------------------------------------------------");
12169            }
12170            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12171        }
12172        Binder.restoreCallingIdentity(origId);
12173    }
12174
12175    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12176            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12177        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12178
12179        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12180                dumpPackage);
12181        boolean needSep = printedAnything;
12182
12183        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12184                dumpPackage, needSep, "  mFocusedActivity: ");
12185        if (printed) {
12186            printedAnything = true;
12187            needSep = false;
12188        }
12189
12190        if (dumpPackage == null) {
12191            if (needSep) {
12192                pw.println();
12193            }
12194            needSep = true;
12195            printedAnything = true;
12196            mStackSupervisor.dump(pw, "  ");
12197        }
12198
12199        if (!printedAnything) {
12200            pw.println("  (nothing)");
12201        }
12202    }
12203
12204    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12205            int opti, boolean dumpAll, String dumpPackage) {
12206        pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)");
12207
12208        boolean printedAnything = false;
12209
12210        if (mRecentTasks.size() > 0) {
12211            boolean printedHeader = false;
12212
12213            final int N = mRecentTasks.size();
12214            for (int i=0; i<N; i++) {
12215                TaskRecord tr = mRecentTasks.get(i);
12216                if (dumpPackage != null) {
12217                    if (tr.realActivity == null ||
12218                            !dumpPackage.equals(tr.realActivity)) {
12219                        continue;
12220                    }
12221                }
12222                if (!printedHeader) {
12223                    pw.println("  Recent tasks:");
12224                    printedHeader = true;
12225                    printedAnything = true;
12226                }
12227                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12228                        pw.println(tr);
12229                if (dumpAll) {
12230                    mRecentTasks.get(i).dump(pw, "    ");
12231                }
12232            }
12233        }
12234
12235        if (!printedAnything) {
12236            pw.println("  (nothing)");
12237        }
12238    }
12239
12240    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12241            int opti, boolean dumpAll, String dumpPackage) {
12242        boolean needSep = false;
12243        boolean printedAnything = false;
12244        int numPers = 0;
12245
12246        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12247
12248        if (dumpAll) {
12249            final int NP = mProcessNames.getMap().size();
12250            for (int ip=0; ip<NP; ip++) {
12251                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12252                final int NA = procs.size();
12253                for (int ia=0; ia<NA; ia++) {
12254                    ProcessRecord r = procs.valueAt(ia);
12255                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12256                        continue;
12257                    }
12258                    if (!needSep) {
12259                        pw.println("  All known processes:");
12260                        needSep = true;
12261                        printedAnything = true;
12262                    }
12263                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12264                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12265                        pw.print(" "); pw.println(r);
12266                    r.dump(pw, "    ");
12267                    if (r.persistent) {
12268                        numPers++;
12269                    }
12270                }
12271            }
12272        }
12273
12274        if (mIsolatedProcesses.size() > 0) {
12275            boolean printed = false;
12276            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12277                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12278                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12279                    continue;
12280                }
12281                if (!printed) {
12282                    if (needSep) {
12283                        pw.println();
12284                    }
12285                    pw.println("  Isolated process list (sorted by uid):");
12286                    printedAnything = true;
12287                    printed = true;
12288                    needSep = true;
12289                }
12290                pw.println(String.format("%sIsolated #%2d: %s",
12291                        "    ", i, r.toString()));
12292            }
12293        }
12294
12295        if (mLruProcesses.size() > 0) {
12296            if (needSep) {
12297                pw.println();
12298            }
12299            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12300                    pw.print(" total, non-act at ");
12301                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12302                    pw.print(", non-svc at ");
12303                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12304                    pw.println("):");
12305            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12306            needSep = true;
12307            printedAnything = true;
12308        }
12309
12310        if (dumpAll || dumpPackage != null) {
12311            synchronized (mPidsSelfLocked) {
12312                boolean printed = false;
12313                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12314                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12315                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12316                        continue;
12317                    }
12318                    if (!printed) {
12319                        if (needSep) pw.println();
12320                        needSep = true;
12321                        pw.println("  PID mappings:");
12322                        printed = true;
12323                        printedAnything = true;
12324                    }
12325                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12326                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12327                }
12328            }
12329        }
12330
12331        if (mForegroundProcesses.size() > 0) {
12332            synchronized (mPidsSelfLocked) {
12333                boolean printed = false;
12334                for (int i=0; i<mForegroundProcesses.size(); i++) {
12335                    ProcessRecord r = mPidsSelfLocked.get(
12336                            mForegroundProcesses.valueAt(i).pid);
12337                    if (dumpPackage != null && (r == null
12338                            || !r.pkgList.containsKey(dumpPackage))) {
12339                        continue;
12340                    }
12341                    if (!printed) {
12342                        if (needSep) pw.println();
12343                        needSep = true;
12344                        pw.println("  Foreground Processes:");
12345                        printed = true;
12346                        printedAnything = true;
12347                    }
12348                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12349                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12350                }
12351            }
12352        }
12353
12354        if (mPersistentStartingProcesses.size() > 0) {
12355            if (needSep) pw.println();
12356            needSep = true;
12357            printedAnything = true;
12358            pw.println("  Persisent processes that are starting:");
12359            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12360                    "Starting Norm", "Restarting PERS", dumpPackage);
12361        }
12362
12363        if (mRemovedProcesses.size() > 0) {
12364            if (needSep) pw.println();
12365            needSep = true;
12366            printedAnything = true;
12367            pw.println("  Processes that are being removed:");
12368            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12369                    "Removed Norm", "Removed PERS", dumpPackage);
12370        }
12371
12372        if (mProcessesOnHold.size() > 0) {
12373            if (needSep) pw.println();
12374            needSep = true;
12375            printedAnything = true;
12376            pw.println("  Processes that are on old until the system is ready:");
12377            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12378                    "OnHold Norm", "OnHold PERS", dumpPackage);
12379        }
12380
12381        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12382
12383        if (mProcessCrashTimes.getMap().size() > 0) {
12384            boolean printed = false;
12385            long now = SystemClock.uptimeMillis();
12386            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12387            final int NP = pmap.size();
12388            for (int ip=0; ip<NP; ip++) {
12389                String pname = pmap.keyAt(ip);
12390                SparseArray<Long> uids = pmap.valueAt(ip);
12391                final int N = uids.size();
12392                for (int i=0; i<N; i++) {
12393                    int puid = uids.keyAt(i);
12394                    ProcessRecord r = mProcessNames.get(pname, puid);
12395                    if (dumpPackage != null && (r == null
12396                            || !r.pkgList.containsKey(dumpPackage))) {
12397                        continue;
12398                    }
12399                    if (!printed) {
12400                        if (needSep) pw.println();
12401                        needSep = true;
12402                        pw.println("  Time since processes crashed:");
12403                        printed = true;
12404                        printedAnything = true;
12405                    }
12406                    pw.print("    Process "); pw.print(pname);
12407                            pw.print(" uid "); pw.print(puid);
12408                            pw.print(": last crashed ");
12409                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12410                            pw.println(" ago");
12411                }
12412            }
12413        }
12414
12415        if (mBadProcesses.getMap().size() > 0) {
12416            boolean printed = false;
12417            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12418            final int NP = pmap.size();
12419            for (int ip=0; ip<NP; ip++) {
12420                String pname = pmap.keyAt(ip);
12421                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12422                final int N = uids.size();
12423                for (int i=0; i<N; i++) {
12424                    int puid = uids.keyAt(i);
12425                    ProcessRecord r = mProcessNames.get(pname, puid);
12426                    if (dumpPackage != null && (r == null
12427                            || !r.pkgList.containsKey(dumpPackage))) {
12428                        continue;
12429                    }
12430                    if (!printed) {
12431                        if (needSep) pw.println();
12432                        needSep = true;
12433                        pw.println("  Bad processes:");
12434                        printedAnything = true;
12435                    }
12436                    BadProcessInfo info = uids.valueAt(i);
12437                    pw.print("    Bad process "); pw.print(pname);
12438                            pw.print(" uid "); pw.print(puid);
12439                            pw.print(": crashed at time "); pw.println(info.time);
12440                    if (info.shortMsg != null) {
12441                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12442                    }
12443                    if (info.longMsg != null) {
12444                        pw.print("      Long msg: "); pw.println(info.longMsg);
12445                    }
12446                    if (info.stack != null) {
12447                        pw.println("      Stack:");
12448                        int lastPos = 0;
12449                        for (int pos=0; pos<info.stack.length(); pos++) {
12450                            if (info.stack.charAt(pos) == '\n') {
12451                                pw.print("        ");
12452                                pw.write(info.stack, lastPos, pos-lastPos);
12453                                pw.println();
12454                                lastPos = pos+1;
12455                            }
12456                        }
12457                        if (lastPos < info.stack.length()) {
12458                            pw.print("        ");
12459                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12460                            pw.println();
12461                        }
12462                    }
12463                }
12464            }
12465        }
12466
12467        if (dumpPackage == null) {
12468            pw.println();
12469            needSep = false;
12470            pw.println("  mStartedUsers:");
12471            for (int i=0; i<mStartedUsers.size(); i++) {
12472                UserStartedState uss = mStartedUsers.valueAt(i);
12473                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12474                        pw.print(": "); uss.dump("", pw);
12475            }
12476            pw.print("  mStartedUserArray: [");
12477            for (int i=0; i<mStartedUserArray.length; i++) {
12478                if (i > 0) pw.print(", ");
12479                pw.print(mStartedUserArray[i]);
12480            }
12481            pw.println("]");
12482            pw.print("  mUserLru: [");
12483            for (int i=0; i<mUserLru.size(); i++) {
12484                if (i > 0) pw.print(", ");
12485                pw.print(mUserLru.get(i));
12486            }
12487            pw.println("]");
12488            if (dumpAll) {
12489                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12490            }
12491            synchronized (mUserProfileGroupIdsSelfLocked) {
12492                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12493                    pw.println("  mUserProfileGroupIds:");
12494                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12495                        pw.print("    User #");
12496                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12497                        pw.print(" -> profile #");
12498                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12499                    }
12500                }
12501            }
12502        }
12503        if (mHomeProcess != null && (dumpPackage == null
12504                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12505            if (needSep) {
12506                pw.println();
12507                needSep = false;
12508            }
12509            pw.println("  mHomeProcess: " + mHomeProcess);
12510        }
12511        if (mPreviousProcess != null && (dumpPackage == null
12512                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12513            if (needSep) {
12514                pw.println();
12515                needSep = false;
12516            }
12517            pw.println("  mPreviousProcess: " + mPreviousProcess);
12518        }
12519        if (dumpAll) {
12520            StringBuilder sb = new StringBuilder(128);
12521            sb.append("  mPreviousProcessVisibleTime: ");
12522            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12523            pw.println(sb);
12524        }
12525        if (mHeavyWeightProcess != null && (dumpPackage == null
12526                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12527            if (needSep) {
12528                pw.println();
12529                needSep = false;
12530            }
12531            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12532        }
12533        if (dumpPackage == null) {
12534            pw.println("  mConfiguration: " + mConfiguration);
12535        }
12536        if (dumpAll) {
12537            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12538            if (mCompatModePackages.getPackages().size() > 0) {
12539                boolean printed = false;
12540                for (Map.Entry<String, Integer> entry
12541                        : mCompatModePackages.getPackages().entrySet()) {
12542                    String pkg = entry.getKey();
12543                    int mode = entry.getValue();
12544                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12545                        continue;
12546                    }
12547                    if (!printed) {
12548                        pw.println("  mScreenCompatPackages:");
12549                        printed = true;
12550                    }
12551                    pw.print("    "); pw.print(pkg); pw.print(": ");
12552                            pw.print(mode); pw.println();
12553                }
12554            }
12555        }
12556        if (dumpPackage == null) {
12557            if (mSleeping || mWentToSleep || mLockScreenShown) {
12558                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12559                        + " mLockScreenShown " + mLockScreenShown);
12560            }
12561            if (mShuttingDown || mRunningVoice) {
12562                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12563            }
12564        }
12565        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12566                || mOrigWaitForDebugger) {
12567            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12568                    || dumpPackage.equals(mOrigDebugApp)) {
12569                if (needSep) {
12570                    pw.println();
12571                    needSep = false;
12572                }
12573                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12574                        + " mDebugTransient=" + mDebugTransient
12575                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12576            }
12577        }
12578        if (mOpenGlTraceApp != null) {
12579            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12580                if (needSep) {
12581                    pw.println();
12582                    needSep = false;
12583                }
12584                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12585            }
12586        }
12587        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12588                || mProfileFd != null) {
12589            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12590                if (needSep) {
12591                    pw.println();
12592                    needSep = false;
12593                }
12594                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12595                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12596                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
12597                        + mAutoStopProfiler);
12598            }
12599        }
12600        if (dumpPackage == null) {
12601            if (mAlwaysFinishActivities || mController != null) {
12602                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12603                        + " mController=" + mController);
12604            }
12605            if (dumpAll) {
12606                pw.println("  Total persistent processes: " + numPers);
12607                pw.println("  mProcessesReady=" + mProcessesReady
12608                        + " mSystemReady=" + mSystemReady);
12609                pw.println("  mBooting=" + mBooting
12610                        + " mBooted=" + mBooted
12611                        + " mFactoryTest=" + mFactoryTest);
12612                pw.print("  mLastPowerCheckRealtime=");
12613                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12614                        pw.println("");
12615                pw.print("  mLastPowerCheckUptime=");
12616                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12617                        pw.println("");
12618                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12619                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12620                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12621                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12622                        + " (" + mLruProcesses.size() + " total)"
12623                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12624                        + " mNumServiceProcs=" + mNumServiceProcs
12625                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12626                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12627                        + " mLastMemoryLevel" + mLastMemoryLevel
12628                        + " mLastNumProcesses" + mLastNumProcesses);
12629                long now = SystemClock.uptimeMillis();
12630                pw.print("  mLastIdleTime=");
12631                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12632                        pw.print(" mLowRamSinceLastIdle=");
12633                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12634                        pw.println();
12635            }
12636        }
12637
12638        if (!printedAnything) {
12639            pw.println("  (nothing)");
12640        }
12641    }
12642
12643    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12644            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12645        if (mProcessesToGc.size() > 0) {
12646            boolean printed = false;
12647            long now = SystemClock.uptimeMillis();
12648            for (int i=0; i<mProcessesToGc.size(); i++) {
12649                ProcessRecord proc = mProcessesToGc.get(i);
12650                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12651                    continue;
12652                }
12653                if (!printed) {
12654                    if (needSep) pw.println();
12655                    needSep = true;
12656                    pw.println("  Processes that are waiting to GC:");
12657                    printed = true;
12658                }
12659                pw.print("    Process "); pw.println(proc);
12660                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12661                        pw.print(", last gced=");
12662                        pw.print(now-proc.lastRequestedGc);
12663                        pw.print(" ms ago, last lowMem=");
12664                        pw.print(now-proc.lastLowMemory);
12665                        pw.println(" ms ago");
12666
12667            }
12668        }
12669        return needSep;
12670    }
12671
12672    void printOomLevel(PrintWriter pw, String name, int adj) {
12673        pw.print("    ");
12674        if (adj >= 0) {
12675            pw.print(' ');
12676            if (adj < 10) pw.print(' ');
12677        } else {
12678            if (adj > -10) pw.print(' ');
12679        }
12680        pw.print(adj);
12681        pw.print(": ");
12682        pw.print(name);
12683        pw.print(" (");
12684        pw.print(mProcessList.getMemLevel(adj)/1024);
12685        pw.println(" kB)");
12686    }
12687
12688    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12689            int opti, boolean dumpAll) {
12690        boolean needSep = false;
12691
12692        if (mLruProcesses.size() > 0) {
12693            if (needSep) pw.println();
12694            needSep = true;
12695            pw.println("  OOM levels:");
12696            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12697            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12698            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12699            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12700            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12701            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12702            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12703            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12704            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12705            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12706            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12707            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12708            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12709
12710            if (needSep) pw.println();
12711            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12712                    pw.print(" total, non-act at ");
12713                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12714                    pw.print(", non-svc at ");
12715                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12716                    pw.println("):");
12717            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12718            needSep = true;
12719        }
12720
12721        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12722
12723        pw.println();
12724        pw.println("  mHomeProcess: " + mHomeProcess);
12725        pw.println("  mPreviousProcess: " + mPreviousProcess);
12726        if (mHeavyWeightProcess != null) {
12727            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12728        }
12729
12730        return true;
12731    }
12732
12733    /**
12734     * There are three ways to call this:
12735     *  - no provider specified: dump all the providers
12736     *  - a flattened component name that matched an existing provider was specified as the
12737     *    first arg: dump that one provider
12738     *  - the first arg isn't the flattened component name of an existing provider:
12739     *    dump all providers whose component contains the first arg as a substring
12740     */
12741    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12742            int opti, boolean dumpAll) {
12743        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12744    }
12745
12746    static class ItemMatcher {
12747        ArrayList<ComponentName> components;
12748        ArrayList<String> strings;
12749        ArrayList<Integer> objects;
12750        boolean all;
12751
12752        ItemMatcher() {
12753            all = true;
12754        }
12755
12756        void build(String name) {
12757            ComponentName componentName = ComponentName.unflattenFromString(name);
12758            if (componentName != null) {
12759                if (components == null) {
12760                    components = new ArrayList<ComponentName>();
12761                }
12762                components.add(componentName);
12763                all = false;
12764            } else {
12765                int objectId = 0;
12766                // Not a '/' separated full component name; maybe an object ID?
12767                try {
12768                    objectId = Integer.parseInt(name, 16);
12769                    if (objects == null) {
12770                        objects = new ArrayList<Integer>();
12771                    }
12772                    objects.add(objectId);
12773                    all = false;
12774                } catch (RuntimeException e) {
12775                    // Not an integer; just do string match.
12776                    if (strings == null) {
12777                        strings = new ArrayList<String>();
12778                    }
12779                    strings.add(name);
12780                    all = false;
12781                }
12782            }
12783        }
12784
12785        int build(String[] args, int opti) {
12786            for (; opti<args.length; opti++) {
12787                String name = args[opti];
12788                if ("--".equals(name)) {
12789                    return opti+1;
12790                }
12791                build(name);
12792            }
12793            return opti;
12794        }
12795
12796        boolean match(Object object, ComponentName comp) {
12797            if (all) {
12798                return true;
12799            }
12800            if (components != null) {
12801                for (int i=0; i<components.size(); i++) {
12802                    if (components.get(i).equals(comp)) {
12803                        return true;
12804                    }
12805                }
12806            }
12807            if (objects != null) {
12808                for (int i=0; i<objects.size(); i++) {
12809                    if (System.identityHashCode(object) == objects.get(i)) {
12810                        return true;
12811                    }
12812                }
12813            }
12814            if (strings != null) {
12815                String flat = comp.flattenToString();
12816                for (int i=0; i<strings.size(); i++) {
12817                    if (flat.contains(strings.get(i))) {
12818                        return true;
12819                    }
12820                }
12821            }
12822            return false;
12823        }
12824    }
12825
12826    /**
12827     * There are three things that cmd can be:
12828     *  - a flattened component name that matches an existing activity
12829     *  - the cmd arg isn't the flattened component name of an existing activity:
12830     *    dump all activity whose component contains the cmd as a substring
12831     *  - A hex number of the ActivityRecord object instance.
12832     */
12833    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12834            int opti, boolean dumpAll) {
12835        ArrayList<ActivityRecord> activities;
12836
12837        synchronized (this) {
12838            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12839        }
12840
12841        if (activities.size() <= 0) {
12842            return false;
12843        }
12844
12845        String[] newArgs = new String[args.length - opti];
12846        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12847
12848        TaskRecord lastTask = null;
12849        boolean needSep = false;
12850        for (int i=activities.size()-1; i>=0; i--) {
12851            ActivityRecord r = activities.get(i);
12852            if (needSep) {
12853                pw.println();
12854            }
12855            needSep = true;
12856            synchronized (this) {
12857                if (lastTask != r.task) {
12858                    lastTask = r.task;
12859                    pw.print("TASK "); pw.print(lastTask.affinity);
12860                            pw.print(" id="); pw.println(lastTask.taskId);
12861                    if (dumpAll) {
12862                        lastTask.dump(pw, "  ");
12863                    }
12864                }
12865            }
12866            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12867        }
12868        return true;
12869    }
12870
12871    /**
12872     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12873     * there is a thread associated with the activity.
12874     */
12875    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12876            final ActivityRecord r, String[] args, boolean dumpAll) {
12877        String innerPrefix = prefix + "  ";
12878        synchronized (this) {
12879            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12880                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12881                    pw.print(" pid=");
12882                    if (r.app != null) pw.println(r.app.pid);
12883                    else pw.println("(not running)");
12884            if (dumpAll) {
12885                r.dump(pw, innerPrefix);
12886            }
12887        }
12888        if (r.app != null && r.app.thread != null) {
12889            // flush anything that is already in the PrintWriter since the thread is going
12890            // to write to the file descriptor directly
12891            pw.flush();
12892            try {
12893                TransferPipe tp = new TransferPipe();
12894                try {
12895                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12896                            r.appToken, innerPrefix, args);
12897                    tp.go(fd);
12898                } finally {
12899                    tp.kill();
12900                }
12901            } catch (IOException e) {
12902                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12903            } catch (RemoteException e) {
12904                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12905            }
12906        }
12907    }
12908
12909    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12910            int opti, boolean dumpAll, String dumpPackage) {
12911        boolean needSep = false;
12912        boolean onlyHistory = false;
12913        boolean printedAnything = false;
12914
12915        if ("history".equals(dumpPackage)) {
12916            if (opti < args.length && "-s".equals(args[opti])) {
12917                dumpAll = false;
12918            }
12919            onlyHistory = true;
12920            dumpPackage = null;
12921        }
12922
12923        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
12924        if (!onlyHistory && dumpAll) {
12925            if (mRegisteredReceivers.size() > 0) {
12926                boolean printed = false;
12927                Iterator it = mRegisteredReceivers.values().iterator();
12928                while (it.hasNext()) {
12929                    ReceiverList r = (ReceiverList)it.next();
12930                    if (dumpPackage != null && (r.app == null ||
12931                            !dumpPackage.equals(r.app.info.packageName))) {
12932                        continue;
12933                    }
12934                    if (!printed) {
12935                        pw.println("  Registered Receivers:");
12936                        needSep = true;
12937                        printed = true;
12938                        printedAnything = true;
12939                    }
12940                    pw.print("  * "); pw.println(r);
12941                    r.dump(pw, "    ");
12942                }
12943            }
12944
12945            if (mReceiverResolver.dump(pw, needSep ?
12946                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
12947                    "    ", dumpPackage, false)) {
12948                needSep = true;
12949                printedAnything = true;
12950            }
12951        }
12952
12953        for (BroadcastQueue q : mBroadcastQueues) {
12954            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
12955            printedAnything |= needSep;
12956        }
12957
12958        needSep = true;
12959
12960        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
12961            for (int user=0; user<mStickyBroadcasts.size(); user++) {
12962                if (needSep) {
12963                    pw.println();
12964                }
12965                needSep = true;
12966                printedAnything = true;
12967                pw.print("  Sticky broadcasts for user ");
12968                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
12969                StringBuilder sb = new StringBuilder(128);
12970                for (Map.Entry<String, ArrayList<Intent>> ent
12971                        : mStickyBroadcasts.valueAt(user).entrySet()) {
12972                    pw.print("  * Sticky action "); pw.print(ent.getKey());
12973                    if (dumpAll) {
12974                        pw.println(":");
12975                        ArrayList<Intent> intents = ent.getValue();
12976                        final int N = intents.size();
12977                        for (int i=0; i<N; i++) {
12978                            sb.setLength(0);
12979                            sb.append("    Intent: ");
12980                            intents.get(i).toShortString(sb, false, true, false, false);
12981                            pw.println(sb.toString());
12982                            Bundle bundle = intents.get(i).getExtras();
12983                            if (bundle != null) {
12984                                pw.print("      ");
12985                                pw.println(bundle.toString());
12986                            }
12987                        }
12988                    } else {
12989                        pw.println("");
12990                    }
12991                }
12992            }
12993        }
12994
12995        if (!onlyHistory && dumpAll) {
12996            pw.println();
12997            for (BroadcastQueue queue : mBroadcastQueues) {
12998                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
12999                        + queue.mBroadcastsScheduled);
13000            }
13001            pw.println("  mHandler:");
13002            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13003            needSep = true;
13004            printedAnything = true;
13005        }
13006
13007        if (!printedAnything) {
13008            pw.println("  (nothing)");
13009        }
13010    }
13011
13012    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13013            int opti, boolean dumpAll, String dumpPackage) {
13014        boolean needSep;
13015        boolean printedAnything = false;
13016
13017        ItemMatcher matcher = new ItemMatcher();
13018        matcher.build(args, opti);
13019
13020        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13021
13022        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13023        printedAnything |= needSep;
13024
13025        if (mLaunchingProviders.size() > 0) {
13026            boolean printed = false;
13027            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13028                ContentProviderRecord r = mLaunchingProviders.get(i);
13029                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13030                    continue;
13031                }
13032                if (!printed) {
13033                    if (needSep) pw.println();
13034                    needSep = true;
13035                    pw.println("  Launching content providers:");
13036                    printed = true;
13037                    printedAnything = true;
13038                }
13039                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13040                        pw.println(r);
13041            }
13042        }
13043
13044        if (mGrantedUriPermissions.size() > 0) {
13045            boolean printed = false;
13046            int dumpUid = -2;
13047            if (dumpPackage != null) {
13048                try {
13049                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13050                } catch (NameNotFoundException e) {
13051                    dumpUid = -1;
13052                }
13053            }
13054            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13055                int uid = mGrantedUriPermissions.keyAt(i);
13056                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13057                    continue;
13058                }
13059                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13060                if (!printed) {
13061                    if (needSep) pw.println();
13062                    needSep = true;
13063                    pw.println("  Granted Uri Permissions:");
13064                    printed = true;
13065                    printedAnything = true;
13066                }
13067                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13068                for (UriPermission perm : perms.values()) {
13069                    pw.print("    "); pw.println(perm);
13070                    if (dumpAll) {
13071                        perm.dump(pw, "      ");
13072                    }
13073                }
13074            }
13075        }
13076
13077        if (!printedAnything) {
13078            pw.println("  (nothing)");
13079        }
13080    }
13081
13082    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13083            int opti, boolean dumpAll, String dumpPackage) {
13084        boolean printed = false;
13085
13086        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13087
13088        if (mIntentSenderRecords.size() > 0) {
13089            Iterator<WeakReference<PendingIntentRecord>> it
13090                    = mIntentSenderRecords.values().iterator();
13091            while (it.hasNext()) {
13092                WeakReference<PendingIntentRecord> ref = it.next();
13093                PendingIntentRecord rec = ref != null ? ref.get(): null;
13094                if (dumpPackage != null && (rec == null
13095                        || !dumpPackage.equals(rec.key.packageName))) {
13096                    continue;
13097                }
13098                printed = true;
13099                if (rec != null) {
13100                    pw.print("  * "); pw.println(rec);
13101                    if (dumpAll) {
13102                        rec.dump(pw, "    ");
13103                    }
13104                } else {
13105                    pw.print("  * "); pw.println(ref);
13106                }
13107            }
13108        }
13109
13110        if (!printed) {
13111            pw.println("  (nothing)");
13112        }
13113    }
13114
13115    private static final int dumpProcessList(PrintWriter pw,
13116            ActivityManagerService service, List list,
13117            String prefix, String normalLabel, String persistentLabel,
13118            String dumpPackage) {
13119        int numPers = 0;
13120        final int N = list.size()-1;
13121        for (int i=N; i>=0; i--) {
13122            ProcessRecord r = (ProcessRecord)list.get(i);
13123            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13124                continue;
13125            }
13126            pw.println(String.format("%s%s #%2d: %s",
13127                    prefix, (r.persistent ? persistentLabel : normalLabel),
13128                    i, r.toString()));
13129            if (r.persistent) {
13130                numPers++;
13131            }
13132        }
13133        return numPers;
13134    }
13135
13136    private static final boolean dumpProcessOomList(PrintWriter pw,
13137            ActivityManagerService service, List<ProcessRecord> origList,
13138            String prefix, String normalLabel, String persistentLabel,
13139            boolean inclDetails, String dumpPackage) {
13140
13141        ArrayList<Pair<ProcessRecord, Integer>> list
13142                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13143        for (int i=0; i<origList.size(); i++) {
13144            ProcessRecord r = origList.get(i);
13145            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13146                continue;
13147            }
13148            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13149        }
13150
13151        if (list.size() <= 0) {
13152            return false;
13153        }
13154
13155        Comparator<Pair<ProcessRecord, Integer>> comparator
13156                = new Comparator<Pair<ProcessRecord, Integer>>() {
13157            @Override
13158            public int compare(Pair<ProcessRecord, Integer> object1,
13159                    Pair<ProcessRecord, Integer> object2) {
13160                if (object1.first.setAdj != object2.first.setAdj) {
13161                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13162                }
13163                if (object1.second.intValue() != object2.second.intValue()) {
13164                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13165                }
13166                return 0;
13167            }
13168        };
13169
13170        Collections.sort(list, comparator);
13171
13172        final long curRealtime = SystemClock.elapsedRealtime();
13173        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13174        final long curUptime = SystemClock.uptimeMillis();
13175        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13176
13177        for (int i=list.size()-1; i>=0; i--) {
13178            ProcessRecord r = list.get(i).first;
13179            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13180            char schedGroup;
13181            switch (r.setSchedGroup) {
13182                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13183                    schedGroup = 'B';
13184                    break;
13185                case Process.THREAD_GROUP_DEFAULT:
13186                    schedGroup = 'F';
13187                    break;
13188                default:
13189                    schedGroup = '?';
13190                    break;
13191            }
13192            char foreground;
13193            if (r.foregroundActivities) {
13194                foreground = 'A';
13195            } else if (r.foregroundServices) {
13196                foreground = 'S';
13197            } else {
13198                foreground = ' ';
13199            }
13200            String procState = ProcessList.makeProcStateString(r.curProcState);
13201            pw.print(prefix);
13202            pw.print(r.persistent ? persistentLabel : normalLabel);
13203            pw.print(" #");
13204            int num = (origList.size()-1)-list.get(i).second;
13205            if (num < 10) pw.print(' ');
13206            pw.print(num);
13207            pw.print(": ");
13208            pw.print(oomAdj);
13209            pw.print(' ');
13210            pw.print(schedGroup);
13211            pw.print('/');
13212            pw.print(foreground);
13213            pw.print('/');
13214            pw.print(procState);
13215            pw.print(" trm:");
13216            if (r.trimMemoryLevel < 10) pw.print(' ');
13217            pw.print(r.trimMemoryLevel);
13218            pw.print(' ');
13219            pw.print(r.toShortString());
13220            pw.print(" (");
13221            pw.print(r.adjType);
13222            pw.println(')');
13223            if (r.adjSource != null || r.adjTarget != null) {
13224                pw.print(prefix);
13225                pw.print("    ");
13226                if (r.adjTarget instanceof ComponentName) {
13227                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13228                } else if (r.adjTarget != null) {
13229                    pw.print(r.adjTarget.toString());
13230                } else {
13231                    pw.print("{null}");
13232                }
13233                pw.print("<=");
13234                if (r.adjSource instanceof ProcessRecord) {
13235                    pw.print("Proc{");
13236                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13237                    pw.println("}");
13238                } else if (r.adjSource != null) {
13239                    pw.println(r.adjSource.toString());
13240                } else {
13241                    pw.println("{null}");
13242                }
13243            }
13244            if (inclDetails) {
13245                pw.print(prefix);
13246                pw.print("    ");
13247                pw.print("oom: max="); pw.print(r.maxAdj);
13248                pw.print(" curRaw="); pw.print(r.curRawAdj);
13249                pw.print(" setRaw="); pw.print(r.setRawAdj);
13250                pw.print(" cur="); pw.print(r.curAdj);
13251                pw.print(" set="); pw.println(r.setAdj);
13252                pw.print(prefix);
13253                pw.print("    ");
13254                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13255                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13256                pw.print(" lastPss="); pw.print(r.lastPss);
13257                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13258                pw.print(prefix);
13259                pw.print("    ");
13260                pw.print("cached="); pw.print(r.cached);
13261                pw.print(" empty="); pw.print(r.empty);
13262                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13263
13264                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13265                    if (r.lastWakeTime != 0) {
13266                        long wtime;
13267                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13268                        synchronized (stats) {
13269                            wtime = stats.getProcessWakeTime(r.info.uid,
13270                                    r.pid, curRealtime);
13271                        }
13272                        long timeUsed = wtime - r.lastWakeTime;
13273                        pw.print(prefix);
13274                        pw.print("    ");
13275                        pw.print("keep awake over ");
13276                        TimeUtils.formatDuration(realtimeSince, pw);
13277                        pw.print(" used ");
13278                        TimeUtils.formatDuration(timeUsed, pw);
13279                        pw.print(" (");
13280                        pw.print((timeUsed*100)/realtimeSince);
13281                        pw.println("%)");
13282                    }
13283                    if (r.lastCpuTime != 0) {
13284                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13285                        pw.print(prefix);
13286                        pw.print("    ");
13287                        pw.print("run cpu over ");
13288                        TimeUtils.formatDuration(uptimeSince, pw);
13289                        pw.print(" used ");
13290                        TimeUtils.formatDuration(timeUsed, pw);
13291                        pw.print(" (");
13292                        pw.print((timeUsed*100)/uptimeSince);
13293                        pw.println("%)");
13294                    }
13295                }
13296            }
13297        }
13298        return true;
13299    }
13300
13301    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
13302        ArrayList<ProcessRecord> procs;
13303        synchronized (this) {
13304            if (args != null && args.length > start
13305                    && args[start].charAt(0) != '-') {
13306                procs = new ArrayList<ProcessRecord>();
13307                int pid = -1;
13308                try {
13309                    pid = Integer.parseInt(args[start]);
13310                } catch (NumberFormatException e) {
13311                }
13312                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13313                    ProcessRecord proc = mLruProcesses.get(i);
13314                    if (proc.pid == pid) {
13315                        procs.add(proc);
13316                    } else if (proc.processName.equals(args[start])) {
13317                        procs.add(proc);
13318                    }
13319                }
13320                if (procs.size() <= 0) {
13321                    return null;
13322                }
13323            } else {
13324                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13325            }
13326        }
13327        return procs;
13328    }
13329
13330    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13331            PrintWriter pw, String[] args) {
13332        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13333        if (procs == null) {
13334            pw.println("No process found for: " + args[0]);
13335            return;
13336        }
13337
13338        long uptime = SystemClock.uptimeMillis();
13339        long realtime = SystemClock.elapsedRealtime();
13340        pw.println("Applications Graphics Acceleration Info:");
13341        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13342
13343        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13344            ProcessRecord r = procs.get(i);
13345            if (r.thread != null) {
13346                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13347                pw.flush();
13348                try {
13349                    TransferPipe tp = new TransferPipe();
13350                    try {
13351                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13352                        tp.go(fd);
13353                    } finally {
13354                        tp.kill();
13355                    }
13356                } catch (IOException e) {
13357                    pw.println("Failure while dumping the app: " + r);
13358                    pw.flush();
13359                } catch (RemoteException e) {
13360                    pw.println("Got a RemoteException while dumping the app " + r);
13361                    pw.flush();
13362                }
13363            }
13364        }
13365    }
13366
13367    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13368        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13369        if (procs == null) {
13370            pw.println("No process found for: " + args[0]);
13371            return;
13372        }
13373
13374        pw.println("Applications Database Info:");
13375
13376        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13377            ProcessRecord r = procs.get(i);
13378            if (r.thread != null) {
13379                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13380                pw.flush();
13381                try {
13382                    TransferPipe tp = new TransferPipe();
13383                    try {
13384                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13385                        tp.go(fd);
13386                    } finally {
13387                        tp.kill();
13388                    }
13389                } catch (IOException e) {
13390                    pw.println("Failure while dumping the app: " + r);
13391                    pw.flush();
13392                } catch (RemoteException e) {
13393                    pw.println("Got a RemoteException while dumping the app " + r);
13394                    pw.flush();
13395                }
13396            }
13397        }
13398    }
13399
13400    final static class MemItem {
13401        final boolean isProc;
13402        final String label;
13403        final String shortLabel;
13404        final long pss;
13405        final int id;
13406        final boolean hasActivities;
13407        ArrayList<MemItem> subitems;
13408
13409        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13410                boolean _hasActivities) {
13411            isProc = true;
13412            label = _label;
13413            shortLabel = _shortLabel;
13414            pss = _pss;
13415            id = _id;
13416            hasActivities = _hasActivities;
13417        }
13418
13419        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13420            isProc = false;
13421            label = _label;
13422            shortLabel = _shortLabel;
13423            pss = _pss;
13424            id = _id;
13425            hasActivities = false;
13426        }
13427    }
13428
13429    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13430            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13431        if (sort && !isCompact) {
13432            Collections.sort(items, new Comparator<MemItem>() {
13433                @Override
13434                public int compare(MemItem lhs, MemItem rhs) {
13435                    if (lhs.pss < rhs.pss) {
13436                        return 1;
13437                    } else if (lhs.pss > rhs.pss) {
13438                        return -1;
13439                    }
13440                    return 0;
13441                }
13442            });
13443        }
13444
13445        for (int i=0; i<items.size(); i++) {
13446            MemItem mi = items.get(i);
13447            if (!isCompact) {
13448                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13449            } else if (mi.isProc) {
13450                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13451                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13452                pw.println(mi.hasActivities ? ",a" : ",e");
13453            } else {
13454                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13455                pw.println(mi.pss);
13456            }
13457            if (mi.subitems != null) {
13458                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13459                        true, isCompact);
13460            }
13461        }
13462    }
13463
13464    // These are in KB.
13465    static final long[] DUMP_MEM_BUCKETS = new long[] {
13466        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13467        120*1024, 160*1024, 200*1024,
13468        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13469        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13470    };
13471
13472    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13473            boolean stackLike) {
13474        int start = label.lastIndexOf('.');
13475        if (start >= 0) start++;
13476        else start = 0;
13477        int end = label.length();
13478        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13479            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13480                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13481                out.append(bucket);
13482                out.append(stackLike ? "MB." : "MB ");
13483                out.append(label, start, end);
13484                return;
13485            }
13486        }
13487        out.append(memKB/1024);
13488        out.append(stackLike ? "MB." : "MB ");
13489        out.append(label, start, end);
13490    }
13491
13492    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13493            ProcessList.NATIVE_ADJ,
13494            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13495            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13496            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13497            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13498            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13499    };
13500    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13501            "Native",
13502            "System", "Persistent", "Foreground",
13503            "Visible", "Perceptible",
13504            "Heavy Weight", "Backup",
13505            "A Services", "Home",
13506            "Previous", "B Services", "Cached"
13507    };
13508    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13509            "native",
13510            "sys", "pers", "fore",
13511            "vis", "percept",
13512            "heavy", "backup",
13513            "servicea", "home",
13514            "prev", "serviceb", "cached"
13515    };
13516
13517    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13518            long realtime, boolean isCheckinRequest, boolean isCompact) {
13519        if (isCheckinRequest || isCompact) {
13520            // short checkin version
13521            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13522        } else {
13523            pw.println("Applications Memory Usage (kB):");
13524            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13525        }
13526    }
13527
13528    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13529            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13530        boolean dumpDetails = false;
13531        boolean dumpFullDetails = false;
13532        boolean dumpDalvik = false;
13533        boolean oomOnly = false;
13534        boolean isCompact = false;
13535        boolean localOnly = false;
13536
13537        int opti = 0;
13538        while (opti < args.length) {
13539            String opt = args[opti];
13540            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13541                break;
13542            }
13543            opti++;
13544            if ("-a".equals(opt)) {
13545                dumpDetails = true;
13546                dumpFullDetails = true;
13547                dumpDalvik = true;
13548            } else if ("-d".equals(opt)) {
13549                dumpDalvik = true;
13550            } else if ("-c".equals(opt)) {
13551                isCompact = true;
13552            } else if ("--oom".equals(opt)) {
13553                oomOnly = true;
13554            } else if ("--local".equals(opt)) {
13555                localOnly = true;
13556            } else if ("-h".equals(opt)) {
13557                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13558                pw.println("  -a: include all available information for each process.");
13559                pw.println("  -d: include dalvik details when dumping process details.");
13560                pw.println("  -c: dump in a compact machine-parseable representation.");
13561                pw.println("  --oom: only show processes organized by oom adj.");
13562                pw.println("  --local: only collect details locally, don't call process.");
13563                pw.println("If [process] is specified it can be the name or ");
13564                pw.println("pid of a specific process to dump.");
13565                return;
13566            } else {
13567                pw.println("Unknown argument: " + opt + "; use -h for help");
13568            }
13569        }
13570
13571        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13572        long uptime = SystemClock.uptimeMillis();
13573        long realtime = SystemClock.elapsedRealtime();
13574        final long[] tmpLong = new long[1];
13575
13576        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
13577        if (procs == null) {
13578            // No Java processes.  Maybe they want to print a native process.
13579            if (args != null && args.length > opti
13580                    && args[opti].charAt(0) != '-') {
13581                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13582                        = new ArrayList<ProcessCpuTracker.Stats>();
13583                updateCpuStatsNow();
13584                int findPid = -1;
13585                try {
13586                    findPid = Integer.parseInt(args[opti]);
13587                } catch (NumberFormatException e) {
13588                }
13589                synchronized (mProcessCpuThread) {
13590                    final int N = mProcessCpuTracker.countStats();
13591                    for (int i=0; i<N; i++) {
13592                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13593                        if (st.pid == findPid || (st.baseName != null
13594                                && st.baseName.equals(args[opti]))) {
13595                            nativeProcs.add(st);
13596                        }
13597                    }
13598                }
13599                if (nativeProcs.size() > 0) {
13600                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13601                            isCompact);
13602                    Debug.MemoryInfo mi = null;
13603                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13604                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13605                        final int pid = r.pid;
13606                        if (!isCheckinRequest && dumpDetails) {
13607                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13608                        }
13609                        if (mi == null) {
13610                            mi = new Debug.MemoryInfo();
13611                        }
13612                        if (dumpDetails || (!brief && !oomOnly)) {
13613                            Debug.getMemoryInfo(pid, mi);
13614                        } else {
13615                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13616                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13617                        }
13618                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13619                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13620                        if (isCheckinRequest) {
13621                            pw.println();
13622                        }
13623                    }
13624                    return;
13625                }
13626            }
13627            pw.println("No process found for: " + args[opti]);
13628            return;
13629        }
13630
13631        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13632            dumpDetails = true;
13633        }
13634
13635        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13636
13637        String[] innerArgs = new String[args.length-opti];
13638        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13639
13640        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13641        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13642        long nativePss=0, dalvikPss=0, otherPss=0;
13643        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13644
13645        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13646        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13647                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13648
13649        long totalPss = 0;
13650        long cachedPss = 0;
13651
13652        Debug.MemoryInfo mi = null;
13653        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13654            final ProcessRecord r = procs.get(i);
13655            final IApplicationThread thread;
13656            final int pid;
13657            final int oomAdj;
13658            final boolean hasActivities;
13659            synchronized (this) {
13660                thread = r.thread;
13661                pid = r.pid;
13662                oomAdj = r.getSetAdjWithServices();
13663                hasActivities = r.activities.size() > 0;
13664            }
13665            if (thread != null) {
13666                if (!isCheckinRequest && dumpDetails) {
13667                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13668                }
13669                if (mi == null) {
13670                    mi = new Debug.MemoryInfo();
13671                }
13672                if (dumpDetails || (!brief && !oomOnly)) {
13673                    Debug.getMemoryInfo(pid, mi);
13674                } else {
13675                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13676                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13677                }
13678                if (dumpDetails) {
13679                    if (localOnly) {
13680                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13681                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13682                        if (isCheckinRequest) {
13683                            pw.println();
13684                        }
13685                    } else {
13686                        try {
13687                            pw.flush();
13688                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13689                                    dumpDalvik, innerArgs);
13690                        } catch (RemoteException e) {
13691                            if (!isCheckinRequest) {
13692                                pw.println("Got RemoteException!");
13693                                pw.flush();
13694                            }
13695                        }
13696                    }
13697                }
13698
13699                final long myTotalPss = mi.getTotalPss();
13700                final long myTotalUss = mi.getTotalUss();
13701
13702                synchronized (this) {
13703                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13704                        // Record this for posterity if the process has been stable.
13705                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13706                    }
13707                }
13708
13709                if (!isCheckinRequest && mi != null) {
13710                    totalPss += myTotalPss;
13711                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13712                            (hasActivities ? " / activities)" : ")"),
13713                            r.processName, myTotalPss, pid, hasActivities);
13714                    procMems.add(pssItem);
13715                    procMemsMap.put(pid, pssItem);
13716
13717                    nativePss += mi.nativePss;
13718                    dalvikPss += mi.dalvikPss;
13719                    otherPss += mi.otherPss;
13720                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13721                        long mem = mi.getOtherPss(j);
13722                        miscPss[j] += mem;
13723                        otherPss -= mem;
13724                    }
13725
13726                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13727                        cachedPss += myTotalPss;
13728                    }
13729
13730                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13731                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13732                                || oomIndex == (oomPss.length-1)) {
13733                            oomPss[oomIndex] += myTotalPss;
13734                            if (oomProcs[oomIndex] == null) {
13735                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13736                            }
13737                            oomProcs[oomIndex].add(pssItem);
13738                            break;
13739                        }
13740                    }
13741                }
13742            }
13743        }
13744
13745        long nativeProcTotalPss = 0;
13746
13747        if (!isCheckinRequest && procs.size() > 1) {
13748            // If we are showing aggregations, also look for native processes to
13749            // include so that our aggregations are more accurate.
13750            updateCpuStatsNow();
13751            synchronized (mProcessCpuThread) {
13752                final int N = mProcessCpuTracker.countStats();
13753                for (int i=0; i<N; i++) {
13754                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13755                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13756                        if (mi == null) {
13757                            mi = new Debug.MemoryInfo();
13758                        }
13759                        if (!brief && !oomOnly) {
13760                            Debug.getMemoryInfo(st.pid, mi);
13761                        } else {
13762                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
13763                            mi.nativePrivateDirty = (int)tmpLong[0];
13764                        }
13765
13766                        final long myTotalPss = mi.getTotalPss();
13767                        totalPss += myTotalPss;
13768                        nativeProcTotalPss += myTotalPss;
13769
13770                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13771                                st.name, myTotalPss, st.pid, false);
13772                        procMems.add(pssItem);
13773
13774                        nativePss += mi.nativePss;
13775                        dalvikPss += mi.dalvikPss;
13776                        otherPss += mi.otherPss;
13777                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13778                            long mem = mi.getOtherPss(j);
13779                            miscPss[j] += mem;
13780                            otherPss -= mem;
13781                        }
13782                        oomPss[0] += myTotalPss;
13783                        if (oomProcs[0] == null) {
13784                            oomProcs[0] = new ArrayList<MemItem>();
13785                        }
13786                        oomProcs[0].add(pssItem);
13787                    }
13788                }
13789            }
13790
13791            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13792
13793            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13794            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13795            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13796            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13797                String label = Debug.MemoryInfo.getOtherLabel(j);
13798                catMems.add(new MemItem(label, label, miscPss[j], j));
13799            }
13800
13801            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13802            for (int j=0; j<oomPss.length; j++) {
13803                if (oomPss[j] != 0) {
13804                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13805                            : DUMP_MEM_OOM_LABEL[j];
13806                    MemItem item = new MemItem(label, label, oomPss[j],
13807                            DUMP_MEM_OOM_ADJ[j]);
13808                    item.subitems = oomProcs[j];
13809                    oomMems.add(item);
13810                }
13811            }
13812
13813            if (!brief && !oomOnly && !isCompact) {
13814                pw.println();
13815                pw.println("Total PSS by process:");
13816                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13817                pw.println();
13818            }
13819            if (!isCompact) {
13820                pw.println("Total PSS by OOM adjustment:");
13821            }
13822            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13823            if (!brief && !oomOnly) {
13824                PrintWriter out = categoryPw != null ? categoryPw : pw;
13825                if (!isCompact) {
13826                    out.println();
13827                    out.println("Total PSS by category:");
13828                }
13829                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13830            }
13831            if (!isCompact) {
13832                pw.println();
13833            }
13834            MemInfoReader memInfo = new MemInfoReader();
13835            memInfo.readMemInfo();
13836            if (nativeProcTotalPss > 0) {
13837                synchronized (this) {
13838                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13839                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13840                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13841                            nativeProcTotalPss);
13842                }
13843            }
13844            if (!brief) {
13845                if (!isCompact) {
13846                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13847                    pw.print(" kB (status ");
13848                    switch (mLastMemoryLevel) {
13849                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13850                            pw.println("normal)");
13851                            break;
13852                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13853                            pw.println("moderate)");
13854                            break;
13855                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13856                            pw.println("low)");
13857                            break;
13858                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13859                            pw.println("critical)");
13860                            break;
13861                        default:
13862                            pw.print(mLastMemoryLevel);
13863                            pw.println(")");
13864                            break;
13865                    }
13866                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13867                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13868                            pw.print(cachedPss); pw.print(" cached pss + ");
13869                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13870                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13871                } else {
13872                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13873                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13874                            + memInfo.getFreeSizeKb()); pw.print(",");
13875                    pw.println(totalPss - cachedPss);
13876                }
13877            }
13878            if (!isCompact) {
13879                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13880                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
13881                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
13882                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13883                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
13884                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
13885                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
13886                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13887                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13888                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
13889                        - memInfo.getSlabSizeKb()); pw.println(" kB");
13890            }
13891            if (!brief) {
13892                if (memInfo.getZramTotalSizeKb() != 0) {
13893                    if (!isCompact) {
13894                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
13895                                pw.print(" kB physical used for ");
13896                                pw.print(memInfo.getSwapTotalSizeKb()
13897                                        - memInfo.getSwapFreeSizeKb());
13898                                pw.print(" kB in swap (");
13899                                pw.print(memInfo.getSwapTotalSizeKb());
13900                                pw.println(" kB total swap)");
13901                    } else {
13902                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13903                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13904                                pw.println(memInfo.getSwapFreeSizeKb());
13905                    }
13906                }
13907                final int[] SINGLE_LONG_FORMAT = new int[] {
13908                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13909                };
13910                long[] longOut = new long[1];
13911                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13912                        SINGLE_LONG_FORMAT, null, longOut, null);
13913                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13914                longOut[0] = 0;
13915                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13916                        SINGLE_LONG_FORMAT, null, longOut, null);
13917                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13918                longOut[0] = 0;
13919                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13920                        SINGLE_LONG_FORMAT, null, longOut, null);
13921                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13922                longOut[0] = 0;
13923                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13924                        SINGLE_LONG_FORMAT, null, longOut, null);
13925                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13926                if (!isCompact) {
13927                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
13928                        pw.print("      KSM: "); pw.print(sharing);
13929                                pw.print(" kB saved from shared ");
13930                                pw.print(shared); pw.println(" kB");
13931                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
13932                                pw.print(voltile); pw.println(" kB volatile");
13933                    }
13934                    pw.print("   Tuning: ");
13935                    pw.print(ActivityManager.staticGetMemoryClass());
13936                    pw.print(" (large ");
13937                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13938                    pw.print("), oom ");
13939                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13940                    pw.print(" kB");
13941                    pw.print(", restore limit ");
13942                    pw.print(mProcessList.getCachedRestoreThresholdKb());
13943                    pw.print(" kB");
13944                    if (ActivityManager.isLowRamDeviceStatic()) {
13945                        pw.print(" (low-ram)");
13946                    }
13947                    if (ActivityManager.isHighEndGfx()) {
13948                        pw.print(" (high-end-gfx)");
13949                    }
13950                    pw.println();
13951                } else {
13952                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
13953                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
13954                    pw.println(voltile);
13955                    pw.print("tuning,");
13956                    pw.print(ActivityManager.staticGetMemoryClass());
13957                    pw.print(',');
13958                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13959                    pw.print(',');
13960                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13961                    if (ActivityManager.isLowRamDeviceStatic()) {
13962                        pw.print(",low-ram");
13963                    }
13964                    if (ActivityManager.isHighEndGfx()) {
13965                        pw.print(",high-end-gfx");
13966                    }
13967                    pw.println();
13968                }
13969            }
13970        }
13971    }
13972
13973    /**
13974     * Searches array of arguments for the specified string
13975     * @param args array of argument strings
13976     * @param value value to search for
13977     * @return true if the value is contained in the array
13978     */
13979    private static boolean scanArgs(String[] args, String value) {
13980        if (args != null) {
13981            for (String arg : args) {
13982                if (value.equals(arg)) {
13983                    return true;
13984                }
13985            }
13986        }
13987        return false;
13988    }
13989
13990    private final boolean removeDyingProviderLocked(ProcessRecord proc,
13991            ContentProviderRecord cpr, boolean always) {
13992        final boolean inLaunching = mLaunchingProviders.contains(cpr);
13993
13994        if (!inLaunching || always) {
13995            synchronized (cpr) {
13996                cpr.launchingApp = null;
13997                cpr.notifyAll();
13998            }
13999            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14000            String names[] = cpr.info.authority.split(";");
14001            for (int j = 0; j < names.length; j++) {
14002                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14003            }
14004        }
14005
14006        for (int i=0; i<cpr.connections.size(); i++) {
14007            ContentProviderConnection conn = cpr.connections.get(i);
14008            if (conn.waiting) {
14009                // If this connection is waiting for the provider, then we don't
14010                // need to mess with its process unless we are always removing
14011                // or for some reason the provider is not currently launching.
14012                if (inLaunching && !always) {
14013                    continue;
14014                }
14015            }
14016            ProcessRecord capp = conn.client;
14017            conn.dead = true;
14018            if (conn.stableCount > 0) {
14019                if (!capp.persistent && capp.thread != null
14020                        && capp.pid != 0
14021                        && capp.pid != MY_PID) {
14022                    capp.kill("depends on provider "
14023                            + cpr.name.flattenToShortString()
14024                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14025                }
14026            } else if (capp.thread != null && conn.provider.provider != null) {
14027                try {
14028                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14029                } catch (RemoteException e) {
14030                }
14031                // In the protocol here, we don't expect the client to correctly
14032                // clean up this connection, we'll just remove it.
14033                cpr.connections.remove(i);
14034                conn.client.conProviders.remove(conn);
14035            }
14036        }
14037
14038        if (inLaunching && always) {
14039            mLaunchingProviders.remove(cpr);
14040        }
14041        return inLaunching;
14042    }
14043
14044    /**
14045     * Main code for cleaning up a process when it has gone away.  This is
14046     * called both as a result of the process dying, or directly when stopping
14047     * a process when running in single process mode.
14048     */
14049    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
14050            boolean restarting, boolean allowRestart, int index) {
14051        if (index >= 0) {
14052            removeLruProcessLocked(app);
14053            ProcessList.remove(app.pid);
14054        }
14055
14056        mProcessesToGc.remove(app);
14057        mPendingPssProcesses.remove(app);
14058
14059        // Dismiss any open dialogs.
14060        if (app.crashDialog != null && !app.forceCrashReport) {
14061            app.crashDialog.dismiss();
14062            app.crashDialog = null;
14063        }
14064        if (app.anrDialog != null) {
14065            app.anrDialog.dismiss();
14066            app.anrDialog = null;
14067        }
14068        if (app.waitDialog != null) {
14069            app.waitDialog.dismiss();
14070            app.waitDialog = null;
14071        }
14072
14073        app.crashing = false;
14074        app.notResponding = false;
14075
14076        app.resetPackageList(mProcessStats);
14077        app.unlinkDeathRecipient();
14078        app.makeInactive(mProcessStats);
14079        app.waitingToKill = null;
14080        app.forcingToForeground = null;
14081        updateProcessForegroundLocked(app, false, false);
14082        app.foregroundActivities = false;
14083        app.hasShownUi = false;
14084        app.treatLikeActivity = false;
14085        app.hasAboveClient = false;
14086        app.hasClientActivities = false;
14087
14088        mServices.killServicesLocked(app, allowRestart);
14089
14090        boolean restart = false;
14091
14092        // Remove published content providers.
14093        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14094            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14095            final boolean always = app.bad || !allowRestart;
14096            if (removeDyingProviderLocked(app, cpr, always) || always) {
14097                // We left the provider in the launching list, need to
14098                // restart it.
14099                restart = true;
14100            }
14101
14102            cpr.provider = null;
14103            cpr.proc = null;
14104        }
14105        app.pubProviders.clear();
14106
14107        // Take care of any launching providers waiting for this process.
14108        if (checkAppInLaunchingProvidersLocked(app, false)) {
14109            restart = true;
14110        }
14111
14112        // Unregister from connected content providers.
14113        if (!app.conProviders.isEmpty()) {
14114            for (int i=0; i<app.conProviders.size(); i++) {
14115                ContentProviderConnection conn = app.conProviders.get(i);
14116                conn.provider.connections.remove(conn);
14117            }
14118            app.conProviders.clear();
14119        }
14120
14121        // At this point there may be remaining entries in mLaunchingProviders
14122        // where we were the only one waiting, so they are no longer of use.
14123        // Look for these and clean up if found.
14124        // XXX Commented out for now.  Trying to figure out a way to reproduce
14125        // the actual situation to identify what is actually going on.
14126        if (false) {
14127            for (int i=0; i<mLaunchingProviders.size(); i++) {
14128                ContentProviderRecord cpr = (ContentProviderRecord)
14129                        mLaunchingProviders.get(i);
14130                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14131                    synchronized (cpr) {
14132                        cpr.launchingApp = null;
14133                        cpr.notifyAll();
14134                    }
14135                }
14136            }
14137        }
14138
14139        skipCurrentReceiverLocked(app);
14140
14141        // Unregister any receivers.
14142        for (int i=app.receivers.size()-1; i>=0; i--) {
14143            removeReceiverLocked(app.receivers.valueAt(i));
14144        }
14145        app.receivers.clear();
14146
14147        // If the app is undergoing backup, tell the backup manager about it
14148        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14149            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14150                    + mBackupTarget.appInfo + " died during backup");
14151            try {
14152                IBackupManager bm = IBackupManager.Stub.asInterface(
14153                        ServiceManager.getService(Context.BACKUP_SERVICE));
14154                bm.agentDisconnected(app.info.packageName);
14155            } catch (RemoteException e) {
14156                // can't happen; backup manager is local
14157            }
14158        }
14159
14160        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14161            ProcessChangeItem item = mPendingProcessChanges.get(i);
14162            if (item.pid == app.pid) {
14163                mPendingProcessChanges.remove(i);
14164                mAvailProcessChanges.add(item);
14165            }
14166        }
14167        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14168
14169        // If the caller is restarting this app, then leave it in its
14170        // current lists and let the caller take care of it.
14171        if (restarting) {
14172            return;
14173        }
14174
14175        if (!app.persistent || app.isolated) {
14176            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14177                    "Removing non-persistent process during cleanup: " + app);
14178            mProcessNames.remove(app.processName, app.uid);
14179            mIsolatedProcesses.remove(app.uid);
14180            if (mHeavyWeightProcess == app) {
14181                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14182                        mHeavyWeightProcess.userId, 0));
14183                mHeavyWeightProcess = null;
14184            }
14185        } else if (!app.removed) {
14186            // This app is persistent, so we need to keep its record around.
14187            // If it is not already on the pending app list, add it there
14188            // and start a new process for it.
14189            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14190                mPersistentStartingProcesses.add(app);
14191                restart = true;
14192            }
14193        }
14194        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14195                "Clean-up removing on hold: " + app);
14196        mProcessesOnHold.remove(app);
14197
14198        if (app == mHomeProcess) {
14199            mHomeProcess = null;
14200        }
14201        if (app == mPreviousProcess) {
14202            mPreviousProcess = null;
14203        }
14204
14205        if (restart && !app.isolated) {
14206            // We have components that still need to be running in the
14207            // process, so re-launch it.
14208            mProcessNames.put(app.processName, app.uid, app);
14209            startProcessLocked(app, "restart", app.processName);
14210        } else if (app.pid > 0 && app.pid != MY_PID) {
14211            // Goodbye!
14212            boolean removed;
14213            synchronized (mPidsSelfLocked) {
14214                mPidsSelfLocked.remove(app.pid);
14215                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14216            }
14217            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14218            if (app.isolated) {
14219                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14220            }
14221            app.setPid(0);
14222        }
14223    }
14224
14225    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14226        // Look through the content providers we are waiting to have launched,
14227        // and if any run in this process then either schedule a restart of
14228        // the process or kill the client waiting for it if this process has
14229        // gone bad.
14230        int NL = mLaunchingProviders.size();
14231        boolean restart = false;
14232        for (int i=0; i<NL; i++) {
14233            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14234            if (cpr.launchingApp == app) {
14235                if (!alwaysBad && !app.bad) {
14236                    restart = true;
14237                } else {
14238                    removeDyingProviderLocked(app, cpr, true);
14239                    // cpr should have been removed from mLaunchingProviders
14240                    NL = mLaunchingProviders.size();
14241                    i--;
14242                }
14243            }
14244        }
14245        return restart;
14246    }
14247
14248    // =========================================================
14249    // SERVICES
14250    // =========================================================
14251
14252    @Override
14253    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14254            int flags) {
14255        enforceNotIsolatedCaller("getServices");
14256        synchronized (this) {
14257            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14258        }
14259    }
14260
14261    @Override
14262    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14263        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14264        synchronized (this) {
14265            return mServices.getRunningServiceControlPanelLocked(name);
14266        }
14267    }
14268
14269    @Override
14270    public ComponentName startService(IApplicationThread caller, Intent service,
14271            String resolvedType, int userId) {
14272        enforceNotIsolatedCaller("startService");
14273        // Refuse possible leaked file descriptors
14274        if (service != null && service.hasFileDescriptors() == true) {
14275            throw new IllegalArgumentException("File descriptors passed in Intent");
14276        }
14277
14278        if (DEBUG_SERVICE)
14279            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14280        synchronized(this) {
14281            final int callingPid = Binder.getCallingPid();
14282            final int callingUid = Binder.getCallingUid();
14283            final long origId = Binder.clearCallingIdentity();
14284            ComponentName res = mServices.startServiceLocked(caller, service,
14285                    resolvedType, callingPid, callingUid, userId);
14286            Binder.restoreCallingIdentity(origId);
14287            return res;
14288        }
14289    }
14290
14291    ComponentName startServiceInPackage(int uid,
14292            Intent service, String resolvedType, int userId) {
14293        synchronized(this) {
14294            if (DEBUG_SERVICE)
14295                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14296            final long origId = Binder.clearCallingIdentity();
14297            ComponentName res = mServices.startServiceLocked(null, service,
14298                    resolvedType, -1, uid, userId);
14299            Binder.restoreCallingIdentity(origId);
14300            return res;
14301        }
14302    }
14303
14304    @Override
14305    public int stopService(IApplicationThread caller, Intent service,
14306            String resolvedType, int userId) {
14307        enforceNotIsolatedCaller("stopService");
14308        // Refuse possible leaked file descriptors
14309        if (service != null && service.hasFileDescriptors() == true) {
14310            throw new IllegalArgumentException("File descriptors passed in Intent");
14311        }
14312
14313        synchronized(this) {
14314            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14315        }
14316    }
14317
14318    @Override
14319    public IBinder peekService(Intent service, String resolvedType) {
14320        enforceNotIsolatedCaller("peekService");
14321        // Refuse possible leaked file descriptors
14322        if (service != null && service.hasFileDescriptors() == true) {
14323            throw new IllegalArgumentException("File descriptors passed in Intent");
14324        }
14325        synchronized(this) {
14326            return mServices.peekServiceLocked(service, resolvedType);
14327        }
14328    }
14329
14330    @Override
14331    public boolean stopServiceToken(ComponentName className, IBinder token,
14332            int startId) {
14333        synchronized(this) {
14334            return mServices.stopServiceTokenLocked(className, token, startId);
14335        }
14336    }
14337
14338    @Override
14339    public void setServiceForeground(ComponentName className, IBinder token,
14340            int id, Notification notification, boolean removeNotification) {
14341        synchronized(this) {
14342            mServices.setServiceForegroundLocked(className, token, id, notification,
14343                    removeNotification);
14344        }
14345    }
14346
14347    @Override
14348    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14349            boolean requireFull, String name, String callerPackage) {
14350        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14351                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14352    }
14353
14354    int unsafeConvertIncomingUser(int userId) {
14355        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14356                ? mCurrentUserId : userId;
14357    }
14358
14359    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14360            int allowMode, String name, String callerPackage) {
14361        final int callingUserId = UserHandle.getUserId(callingUid);
14362        if (callingUserId == userId) {
14363            return userId;
14364        }
14365
14366        // Note that we may be accessing mCurrentUserId outside of a lock...
14367        // shouldn't be a big deal, if this is being called outside
14368        // of a locked context there is intrinsically a race with
14369        // the value the caller will receive and someone else changing it.
14370        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14371        // we will switch to the calling user if access to the current user fails.
14372        int targetUserId = unsafeConvertIncomingUser(userId);
14373
14374        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14375            final boolean allow;
14376            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14377                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14378                // If the caller has this permission, they always pass go.  And collect $200.
14379                allow = true;
14380            } else if (allowMode == ALLOW_FULL_ONLY) {
14381                // We require full access, sucks to be you.
14382                allow = false;
14383            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14384                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14385                // If the caller does not have either permission, they are always doomed.
14386                allow = false;
14387            } else if (allowMode == ALLOW_NON_FULL) {
14388                // We are blanket allowing non-full access, you lucky caller!
14389                allow = true;
14390            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14391                // We may or may not allow this depending on whether the two users are
14392                // in the same profile.
14393                synchronized (mUserProfileGroupIdsSelfLocked) {
14394                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14395                            UserInfo.NO_PROFILE_GROUP_ID);
14396                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14397                            UserInfo.NO_PROFILE_GROUP_ID);
14398                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14399                            && callingProfile == targetProfile;
14400                }
14401            } else {
14402                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14403            }
14404            if (!allow) {
14405                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14406                    // In this case, they would like to just execute as their
14407                    // owner user instead of failing.
14408                    targetUserId = callingUserId;
14409                } else {
14410                    StringBuilder builder = new StringBuilder(128);
14411                    builder.append("Permission Denial: ");
14412                    builder.append(name);
14413                    if (callerPackage != null) {
14414                        builder.append(" from ");
14415                        builder.append(callerPackage);
14416                    }
14417                    builder.append(" asks to run as user ");
14418                    builder.append(userId);
14419                    builder.append(" but is calling from user ");
14420                    builder.append(UserHandle.getUserId(callingUid));
14421                    builder.append("; this requires ");
14422                    builder.append(INTERACT_ACROSS_USERS_FULL);
14423                    if (allowMode != ALLOW_FULL_ONLY) {
14424                        builder.append(" or ");
14425                        builder.append(INTERACT_ACROSS_USERS);
14426                    }
14427                    String msg = builder.toString();
14428                    Slog.w(TAG, msg);
14429                    throw new SecurityException(msg);
14430                }
14431            }
14432        }
14433        if (!allowAll && targetUserId < 0) {
14434            throw new IllegalArgumentException(
14435                    "Call does not support special user #" + targetUserId);
14436        }
14437        return targetUserId;
14438    }
14439
14440    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14441            String className, int flags) {
14442        boolean result = false;
14443        // For apps that don't have pre-defined UIDs, check for permission
14444        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14445            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14446                if (ActivityManager.checkUidPermission(
14447                        INTERACT_ACROSS_USERS,
14448                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14449                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14450                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14451                            + " requests FLAG_SINGLE_USER, but app does not hold "
14452                            + INTERACT_ACROSS_USERS;
14453                    Slog.w(TAG, msg);
14454                    throw new SecurityException(msg);
14455                }
14456                // Permission passed
14457                result = true;
14458            }
14459        } else if ("system".equals(componentProcessName)) {
14460            result = true;
14461        } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14462                && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14463            // Phone app is allowed to export singleuser providers.
14464            result = true;
14465        } else {
14466            // App with pre-defined UID, check if it's a persistent app
14467            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14468        }
14469        if (DEBUG_MU) {
14470            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14471                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14472        }
14473        return result;
14474    }
14475
14476    /**
14477     * Checks to see if the caller is in the same app as the singleton
14478     * component, or the component is in a special app. It allows special apps
14479     * to export singleton components but prevents exporting singleton
14480     * components for regular apps.
14481     */
14482    boolean isValidSingletonCall(int callingUid, int componentUid) {
14483        int componentAppId = UserHandle.getAppId(componentUid);
14484        return UserHandle.isSameApp(callingUid, componentUid)
14485                || componentAppId == Process.SYSTEM_UID
14486                || componentAppId == Process.PHONE_UID
14487                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14488                        == PackageManager.PERMISSION_GRANTED;
14489    }
14490
14491    public int bindService(IApplicationThread caller, IBinder token,
14492            Intent service, String resolvedType,
14493            IServiceConnection connection, int flags, int userId) {
14494        enforceNotIsolatedCaller("bindService");
14495        // Refuse possible leaked file descriptors
14496        if (service != null && service.hasFileDescriptors() == true) {
14497            throw new IllegalArgumentException("File descriptors passed in Intent");
14498        }
14499
14500        synchronized(this) {
14501            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14502                    connection, flags, userId);
14503        }
14504    }
14505
14506    public boolean unbindService(IServiceConnection connection) {
14507        synchronized (this) {
14508            return mServices.unbindServiceLocked(connection);
14509        }
14510    }
14511
14512    public void publishService(IBinder token, Intent intent, IBinder service) {
14513        // Refuse possible leaked file descriptors
14514        if (intent != null && intent.hasFileDescriptors() == true) {
14515            throw new IllegalArgumentException("File descriptors passed in Intent");
14516        }
14517
14518        synchronized(this) {
14519            if (!(token instanceof ServiceRecord)) {
14520                throw new IllegalArgumentException("Invalid service token");
14521            }
14522            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14523        }
14524    }
14525
14526    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14527        // Refuse possible leaked file descriptors
14528        if (intent != null && intent.hasFileDescriptors() == true) {
14529            throw new IllegalArgumentException("File descriptors passed in Intent");
14530        }
14531
14532        synchronized(this) {
14533            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14534        }
14535    }
14536
14537    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14538        synchronized(this) {
14539            if (!(token instanceof ServiceRecord)) {
14540                throw new IllegalArgumentException("Invalid service token");
14541            }
14542            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14543        }
14544    }
14545
14546    // =========================================================
14547    // BACKUP AND RESTORE
14548    // =========================================================
14549
14550    // Cause the target app to be launched if necessary and its backup agent
14551    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14552    // activity manager to announce its creation.
14553    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14554        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14555        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14556
14557        synchronized(this) {
14558            // !!! TODO: currently no check here that we're already bound
14559            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14560            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14561            synchronized (stats) {
14562                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14563            }
14564
14565            // Backup agent is now in use, its package can't be stopped.
14566            try {
14567                AppGlobals.getPackageManager().setPackageStoppedState(
14568                        app.packageName, false, UserHandle.getUserId(app.uid));
14569            } catch (RemoteException e) {
14570            } catch (IllegalArgumentException e) {
14571                Slog.w(TAG, "Failed trying to unstop package "
14572                        + app.packageName + ": " + e);
14573            }
14574
14575            BackupRecord r = new BackupRecord(ss, app, backupMode);
14576            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14577                    ? new ComponentName(app.packageName, app.backupAgentName)
14578                    : new ComponentName("android", "FullBackupAgent");
14579            // startProcessLocked() returns existing proc's record if it's already running
14580            ProcessRecord proc = startProcessLocked(app.processName, app,
14581                    false, 0, "backup", hostingName, false, false, false);
14582            if (proc == null) {
14583                Slog.e(TAG, "Unable to start backup agent process " + r);
14584                return false;
14585            }
14586
14587            r.app = proc;
14588            mBackupTarget = r;
14589            mBackupAppName = app.packageName;
14590
14591            // Try not to kill the process during backup
14592            updateOomAdjLocked(proc);
14593
14594            // If the process is already attached, schedule the creation of the backup agent now.
14595            // If it is not yet live, this will be done when it attaches to the framework.
14596            if (proc.thread != null) {
14597                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14598                try {
14599                    proc.thread.scheduleCreateBackupAgent(app,
14600                            compatibilityInfoForPackageLocked(app), backupMode);
14601                } catch (RemoteException e) {
14602                    // Will time out on the backup manager side
14603                }
14604            } else {
14605                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14606            }
14607            // Invariants: at this point, the target app process exists and the application
14608            // is either already running or in the process of coming up.  mBackupTarget and
14609            // mBackupAppName describe the app, so that when it binds back to the AM we
14610            // know that it's scheduled for a backup-agent operation.
14611        }
14612
14613        return true;
14614    }
14615
14616    @Override
14617    public void clearPendingBackup() {
14618        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14619        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14620
14621        synchronized (this) {
14622            mBackupTarget = null;
14623            mBackupAppName = null;
14624        }
14625    }
14626
14627    // A backup agent has just come up
14628    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14629        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14630                + " = " + agent);
14631
14632        synchronized(this) {
14633            if (!agentPackageName.equals(mBackupAppName)) {
14634                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14635                return;
14636            }
14637        }
14638
14639        long oldIdent = Binder.clearCallingIdentity();
14640        try {
14641            IBackupManager bm = IBackupManager.Stub.asInterface(
14642                    ServiceManager.getService(Context.BACKUP_SERVICE));
14643            bm.agentConnected(agentPackageName, agent);
14644        } catch (RemoteException e) {
14645            // can't happen; the backup manager service is local
14646        } catch (Exception e) {
14647            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14648            e.printStackTrace();
14649        } finally {
14650            Binder.restoreCallingIdentity(oldIdent);
14651        }
14652    }
14653
14654    // done with this agent
14655    public void unbindBackupAgent(ApplicationInfo appInfo) {
14656        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14657        if (appInfo == null) {
14658            Slog.w(TAG, "unbind backup agent for null app");
14659            return;
14660        }
14661
14662        synchronized(this) {
14663            try {
14664                if (mBackupAppName == null) {
14665                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14666                    return;
14667                }
14668
14669                if (!mBackupAppName.equals(appInfo.packageName)) {
14670                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14671                    return;
14672                }
14673
14674                // Not backing this app up any more; reset its OOM adjustment
14675                final ProcessRecord proc = mBackupTarget.app;
14676                updateOomAdjLocked(proc);
14677
14678                // If the app crashed during backup, 'thread' will be null here
14679                if (proc.thread != null) {
14680                    try {
14681                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14682                                compatibilityInfoForPackageLocked(appInfo));
14683                    } catch (Exception e) {
14684                        Slog.e(TAG, "Exception when unbinding backup agent:");
14685                        e.printStackTrace();
14686                    }
14687                }
14688            } finally {
14689                mBackupTarget = null;
14690                mBackupAppName = null;
14691            }
14692        }
14693    }
14694    // =========================================================
14695    // BROADCASTS
14696    // =========================================================
14697
14698    private final List getStickiesLocked(String action, IntentFilter filter,
14699            List cur, int userId) {
14700        final ContentResolver resolver = mContext.getContentResolver();
14701        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14702        if (stickies == null) {
14703            return cur;
14704        }
14705        final ArrayList<Intent> list = stickies.get(action);
14706        if (list == null) {
14707            return cur;
14708        }
14709        int N = list.size();
14710        for (int i=0; i<N; i++) {
14711            Intent intent = list.get(i);
14712            if (filter.match(resolver, intent, true, TAG) >= 0) {
14713                if (cur == null) {
14714                    cur = new ArrayList<Intent>();
14715                }
14716                cur.add(intent);
14717            }
14718        }
14719        return cur;
14720    }
14721
14722    boolean isPendingBroadcastProcessLocked(int pid) {
14723        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
14724                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
14725    }
14726
14727    void skipPendingBroadcastLocked(int pid) {
14728            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
14729            for (BroadcastQueue queue : mBroadcastQueues) {
14730                queue.skipPendingBroadcastLocked(pid);
14731            }
14732    }
14733
14734    // The app just attached; send any pending broadcasts that it should receive
14735    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14736        boolean didSomething = false;
14737        for (BroadcastQueue queue : mBroadcastQueues) {
14738            didSomething |= queue.sendPendingBroadcastsLocked(app);
14739        }
14740        return didSomething;
14741    }
14742
14743    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14744            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
14745        enforceNotIsolatedCaller("registerReceiver");
14746        int callingUid;
14747        int callingPid;
14748        synchronized(this) {
14749            ProcessRecord callerApp = null;
14750            if (caller != null) {
14751                callerApp = getRecordForAppLocked(caller);
14752                if (callerApp == null) {
14753                    throw new SecurityException(
14754                            "Unable to find app for caller " + caller
14755                            + " (pid=" + Binder.getCallingPid()
14756                            + ") when registering receiver " + receiver);
14757                }
14758                if (callerApp.info.uid != Process.SYSTEM_UID &&
14759                        !callerApp.pkgList.containsKey(callerPackage) &&
14760                        !"android".equals(callerPackage)) {
14761                    throw new SecurityException("Given caller package " + callerPackage
14762                            + " is not running in process " + callerApp);
14763                }
14764                callingUid = callerApp.info.uid;
14765                callingPid = callerApp.pid;
14766            } else {
14767                callerPackage = null;
14768                callingUid = Binder.getCallingUid();
14769                callingPid = Binder.getCallingPid();
14770            }
14771
14772            userId = this.handleIncomingUser(callingPid, callingUid, userId,
14773                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
14774
14775            List allSticky = null;
14776
14777            // Look for any matching sticky broadcasts...
14778            Iterator actions = filter.actionsIterator();
14779            if (actions != null) {
14780                while (actions.hasNext()) {
14781                    String action = (String)actions.next();
14782                    allSticky = getStickiesLocked(action, filter, allSticky,
14783                            UserHandle.USER_ALL);
14784                    allSticky = getStickiesLocked(action, filter, allSticky,
14785                            UserHandle.getUserId(callingUid));
14786                }
14787            } else {
14788                allSticky = getStickiesLocked(null, filter, allSticky,
14789                        UserHandle.USER_ALL);
14790                allSticky = getStickiesLocked(null, filter, allSticky,
14791                        UserHandle.getUserId(callingUid));
14792            }
14793
14794            // The first sticky in the list is returned directly back to
14795            // the client.
14796            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14797
14798            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14799                    + ": " + sticky);
14800
14801            if (receiver == null) {
14802                return sticky;
14803            }
14804
14805            ReceiverList rl
14806                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14807            if (rl == null) {
14808                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14809                        userId, receiver);
14810                if (rl.app != null) {
14811                    rl.app.receivers.add(rl);
14812                } else {
14813                    try {
14814                        receiver.asBinder().linkToDeath(rl, 0);
14815                    } catch (RemoteException e) {
14816                        return sticky;
14817                    }
14818                    rl.linkedToDeath = true;
14819                }
14820                mRegisteredReceivers.put(receiver.asBinder(), rl);
14821            } else if (rl.uid != callingUid) {
14822                throw new IllegalArgumentException(
14823                        "Receiver requested to register for uid " + callingUid
14824                        + " was previously registered for uid " + rl.uid);
14825            } else if (rl.pid != callingPid) {
14826                throw new IllegalArgumentException(
14827                        "Receiver requested to register for pid " + callingPid
14828                        + " was previously registered for pid " + rl.pid);
14829            } else if (rl.userId != userId) {
14830                throw new IllegalArgumentException(
14831                        "Receiver requested to register for user " + userId
14832                        + " was previously registered for user " + rl.userId);
14833            }
14834            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14835                    permission, callingUid, userId);
14836            rl.add(bf);
14837            if (!bf.debugCheck()) {
14838                Slog.w(TAG, "==> For Dynamic broadast");
14839            }
14840            mReceiverResolver.addFilter(bf);
14841
14842            // Enqueue broadcasts for all existing stickies that match
14843            // this filter.
14844            if (allSticky != null) {
14845                ArrayList receivers = new ArrayList();
14846                receivers.add(bf);
14847
14848                int N = allSticky.size();
14849                for (int i=0; i<N; i++) {
14850                    Intent intent = (Intent)allSticky.get(i);
14851                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14852                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14853                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14854                            null, null, false, true, true, -1);
14855                    queue.enqueueParallelBroadcastLocked(r);
14856                    queue.scheduleBroadcastsLocked();
14857                }
14858            }
14859
14860            return sticky;
14861        }
14862    }
14863
14864    public void unregisterReceiver(IIntentReceiver receiver) {
14865        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14866
14867        final long origId = Binder.clearCallingIdentity();
14868        try {
14869            boolean doTrim = false;
14870
14871            synchronized(this) {
14872                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14873                if (rl != null) {
14874                    if (rl.curBroadcast != null) {
14875                        BroadcastRecord r = rl.curBroadcast;
14876                        final boolean doNext = finishReceiverLocked(
14877                                receiver.asBinder(), r.resultCode, r.resultData,
14878                                r.resultExtras, r.resultAbort);
14879                        if (doNext) {
14880                            doTrim = true;
14881                            r.queue.processNextBroadcast(false);
14882                        }
14883                    }
14884
14885                    if (rl.app != null) {
14886                        rl.app.receivers.remove(rl);
14887                    }
14888                    removeReceiverLocked(rl);
14889                    if (rl.linkedToDeath) {
14890                        rl.linkedToDeath = false;
14891                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
14892                    }
14893                }
14894            }
14895
14896            // If we actually concluded any broadcasts, we might now be able
14897            // to trim the recipients' apps from our working set
14898            if (doTrim) {
14899                trimApplications();
14900                return;
14901            }
14902
14903        } finally {
14904            Binder.restoreCallingIdentity(origId);
14905        }
14906    }
14907
14908    void removeReceiverLocked(ReceiverList rl) {
14909        mRegisteredReceivers.remove(rl.receiver.asBinder());
14910        int N = rl.size();
14911        for (int i=0; i<N; i++) {
14912            mReceiverResolver.removeFilter(rl.get(i));
14913        }
14914    }
14915
14916    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
14917        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14918            ProcessRecord r = mLruProcesses.get(i);
14919            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
14920                try {
14921                    r.thread.dispatchPackageBroadcast(cmd, packages);
14922                } catch (RemoteException ex) {
14923                }
14924            }
14925        }
14926    }
14927
14928    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
14929            int[] users) {
14930        List<ResolveInfo> receivers = null;
14931        try {
14932            HashSet<ComponentName> singleUserReceivers = null;
14933            boolean scannedFirstReceivers = false;
14934            for (int user : users) {
14935                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
14936                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
14937                if (user != 0 && newReceivers != null) {
14938                    // If this is not the primary user, we need to check for
14939                    // any receivers that should be filtered out.
14940                    for (int i=0; i<newReceivers.size(); i++) {
14941                        ResolveInfo ri = newReceivers.get(i);
14942                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
14943                            newReceivers.remove(i);
14944                            i--;
14945                        }
14946                    }
14947                }
14948                if (newReceivers != null && newReceivers.size() == 0) {
14949                    newReceivers = null;
14950                }
14951                if (receivers == null) {
14952                    receivers = newReceivers;
14953                } else if (newReceivers != null) {
14954                    // We need to concatenate the additional receivers
14955                    // found with what we have do far.  This would be easy,
14956                    // but we also need to de-dup any receivers that are
14957                    // singleUser.
14958                    if (!scannedFirstReceivers) {
14959                        // Collect any single user receivers we had already retrieved.
14960                        scannedFirstReceivers = true;
14961                        for (int i=0; i<receivers.size(); i++) {
14962                            ResolveInfo ri = receivers.get(i);
14963                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14964                                ComponentName cn = new ComponentName(
14965                                        ri.activityInfo.packageName, ri.activityInfo.name);
14966                                if (singleUserReceivers == null) {
14967                                    singleUserReceivers = new HashSet<ComponentName>();
14968                                }
14969                                singleUserReceivers.add(cn);
14970                            }
14971                        }
14972                    }
14973                    // Add the new results to the existing results, tracking
14974                    // and de-dupping single user receivers.
14975                    for (int i=0; i<newReceivers.size(); i++) {
14976                        ResolveInfo ri = newReceivers.get(i);
14977                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14978                            ComponentName cn = new ComponentName(
14979                                    ri.activityInfo.packageName, ri.activityInfo.name);
14980                            if (singleUserReceivers == null) {
14981                                singleUserReceivers = new HashSet<ComponentName>();
14982                            }
14983                            if (!singleUserReceivers.contains(cn)) {
14984                                singleUserReceivers.add(cn);
14985                                receivers.add(ri);
14986                            }
14987                        } else {
14988                            receivers.add(ri);
14989                        }
14990                    }
14991                }
14992            }
14993        } catch (RemoteException ex) {
14994            // pm is in same process, this will never happen.
14995        }
14996        return receivers;
14997    }
14998
14999    private final int broadcastIntentLocked(ProcessRecord callerApp,
15000            String callerPackage, Intent intent, String resolvedType,
15001            IIntentReceiver resultTo, int resultCode, String resultData,
15002            Bundle map, String requiredPermission, int appOp,
15003            boolean ordered, boolean sticky, int callingPid, int callingUid,
15004            int userId) {
15005        intent = new Intent(intent);
15006
15007        // By default broadcasts do not go to stopped apps.
15008        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15009
15010        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15011            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15012            + " ordered=" + ordered + " userid=" + userId);
15013        if ((resultTo != null) && !ordered) {
15014            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15015        }
15016
15017        userId = handleIncomingUser(callingPid, callingUid, userId,
15018                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15019
15020        // Make sure that the user who is receiving this broadcast is started.
15021        // If not, we will just skip it.
15022
15023
15024        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15025            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15026                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15027                Slog.w(TAG, "Skipping broadcast of " + intent
15028                        + ": user " + userId + " is stopped");
15029                return ActivityManager.BROADCAST_SUCCESS;
15030            }
15031        }
15032
15033        /*
15034         * Prevent non-system code (defined here to be non-persistent
15035         * processes) from sending protected broadcasts.
15036         */
15037        int callingAppId = UserHandle.getAppId(callingUid);
15038        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15039            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15040            || callingAppId == Process.NFC_UID || callingUid == 0) {
15041            // Always okay.
15042        } else if (callerApp == null || !callerApp.persistent) {
15043            try {
15044                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15045                        intent.getAction())) {
15046                    String msg = "Permission Denial: not allowed to send broadcast "
15047                            + intent.getAction() + " from pid="
15048                            + callingPid + ", uid=" + callingUid;
15049                    Slog.w(TAG, msg);
15050                    throw new SecurityException(msg);
15051                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15052                    // Special case for compatibility: we don't want apps to send this,
15053                    // but historically it has not been protected and apps may be using it
15054                    // to poke their own app widget.  So, instead of making it protected,
15055                    // just limit it to the caller.
15056                    if (callerApp == null) {
15057                        String msg = "Permission Denial: not allowed to send broadcast "
15058                                + intent.getAction() + " from unknown caller.";
15059                        Slog.w(TAG, msg);
15060                        throw new SecurityException(msg);
15061                    } else if (intent.getComponent() != null) {
15062                        // They are good enough to send to an explicit component...  verify
15063                        // it is being sent to the calling app.
15064                        if (!intent.getComponent().getPackageName().equals(
15065                                callerApp.info.packageName)) {
15066                            String msg = "Permission Denial: not allowed to send broadcast "
15067                                    + intent.getAction() + " to "
15068                                    + intent.getComponent().getPackageName() + " from "
15069                                    + callerApp.info.packageName;
15070                            Slog.w(TAG, msg);
15071                            throw new SecurityException(msg);
15072                        }
15073                    } else {
15074                        // Limit broadcast to their own package.
15075                        intent.setPackage(callerApp.info.packageName);
15076                    }
15077                }
15078            } catch (RemoteException e) {
15079                Slog.w(TAG, "Remote exception", e);
15080                return ActivityManager.BROADCAST_SUCCESS;
15081            }
15082        }
15083
15084        // Handle special intents: if this broadcast is from the package
15085        // manager about a package being removed, we need to remove all of
15086        // its activities from the history stack.
15087        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15088                intent.getAction());
15089        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15090                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15091                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15092                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15093                || uidRemoved) {
15094            if (checkComponentPermission(
15095                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15096                    callingPid, callingUid, -1, true)
15097                    == PackageManager.PERMISSION_GRANTED) {
15098                if (uidRemoved) {
15099                    final Bundle intentExtras = intent.getExtras();
15100                    final int uid = intentExtras != null
15101                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15102                    if (uid >= 0) {
15103                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15104                        synchronized (bs) {
15105                            bs.removeUidStatsLocked(uid);
15106                        }
15107                        mAppOpsService.uidRemoved(uid);
15108                    }
15109                } else {
15110                    // If resources are unavailable just force stop all
15111                    // those packages and flush the attribute cache as well.
15112                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15113                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15114                        if (list != null && (list.length > 0)) {
15115                            for (String pkg : list) {
15116                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15117                                        "storage unmount");
15118                            }
15119                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15120                            sendPackageBroadcastLocked(
15121                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15122                        }
15123                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15124                            intent.getAction())) {
15125                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15126                    } else {
15127                        Uri data = intent.getData();
15128                        String ssp;
15129                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15130                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15131                                    intent.getAction());
15132                            boolean fullUninstall = removed &&
15133                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15134                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15135                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15136                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15137                                        false, fullUninstall, userId,
15138                                        removed ? "pkg removed" : "pkg changed");
15139                            }
15140                            if (removed) {
15141                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15142                                        new String[] {ssp}, userId);
15143                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15144                                    mAppOpsService.packageRemoved(
15145                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15146
15147                                    // Remove all permissions granted from/to this package
15148                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15149                                }
15150                            }
15151                        }
15152                    }
15153                }
15154            } else {
15155                String msg = "Permission Denial: " + intent.getAction()
15156                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15157                        + ", uid=" + callingUid + ")"
15158                        + " requires "
15159                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15160                Slog.w(TAG, msg);
15161                throw new SecurityException(msg);
15162            }
15163
15164        // Special case for adding a package: by default turn on compatibility
15165        // mode.
15166        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15167            Uri data = intent.getData();
15168            String ssp;
15169            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15170                mCompatModePackages.handlePackageAddedLocked(ssp,
15171                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15172            }
15173        }
15174
15175        /*
15176         * If this is the time zone changed action, queue up a message that will reset the timezone
15177         * of all currently running processes. This message will get queued up before the broadcast
15178         * happens.
15179         */
15180        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15181            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15182        }
15183
15184        /*
15185         * If the user set the time, let all running processes know.
15186         */
15187        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15188            final int is24Hour = intent.getBooleanExtra(
15189                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15190            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15191        }
15192
15193        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15194            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15195        }
15196
15197        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15198            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15199            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15200        }
15201
15202        // Add to the sticky list if requested.
15203        if (sticky) {
15204            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15205                    callingPid, callingUid)
15206                    != PackageManager.PERMISSION_GRANTED) {
15207                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15208                        + callingPid + ", uid=" + callingUid
15209                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15210                Slog.w(TAG, msg);
15211                throw new SecurityException(msg);
15212            }
15213            if (requiredPermission != null) {
15214                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15215                        + " and enforce permission " + requiredPermission);
15216                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15217            }
15218            if (intent.getComponent() != null) {
15219                throw new SecurityException(
15220                        "Sticky broadcasts can't target a specific component");
15221            }
15222            // We use userId directly here, since the "all" target is maintained
15223            // as a separate set of sticky broadcasts.
15224            if (userId != UserHandle.USER_ALL) {
15225                // But first, if this is not a broadcast to all users, then
15226                // make sure it doesn't conflict with an existing broadcast to
15227                // all users.
15228                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15229                        UserHandle.USER_ALL);
15230                if (stickies != null) {
15231                    ArrayList<Intent> list = stickies.get(intent.getAction());
15232                    if (list != null) {
15233                        int N = list.size();
15234                        int i;
15235                        for (i=0; i<N; i++) {
15236                            if (intent.filterEquals(list.get(i))) {
15237                                throw new IllegalArgumentException(
15238                                        "Sticky broadcast " + intent + " for user "
15239                                        + userId + " conflicts with existing global broadcast");
15240                            }
15241                        }
15242                    }
15243                }
15244            }
15245            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15246            if (stickies == null) {
15247                stickies = new ArrayMap<String, ArrayList<Intent>>();
15248                mStickyBroadcasts.put(userId, stickies);
15249            }
15250            ArrayList<Intent> list = stickies.get(intent.getAction());
15251            if (list == null) {
15252                list = new ArrayList<Intent>();
15253                stickies.put(intent.getAction(), list);
15254            }
15255            int N = list.size();
15256            int i;
15257            for (i=0; i<N; i++) {
15258                if (intent.filterEquals(list.get(i))) {
15259                    // This sticky already exists, replace it.
15260                    list.set(i, new Intent(intent));
15261                    break;
15262                }
15263            }
15264            if (i >= N) {
15265                list.add(new Intent(intent));
15266            }
15267        }
15268
15269        int[] users;
15270        if (userId == UserHandle.USER_ALL) {
15271            // Caller wants broadcast to go to all started users.
15272            users = mStartedUserArray;
15273        } else {
15274            // Caller wants broadcast to go to one specific user.
15275            users = new int[] {userId};
15276        }
15277
15278        // Figure out who all will receive this broadcast.
15279        List receivers = null;
15280        List<BroadcastFilter> registeredReceivers = null;
15281        // Need to resolve the intent to interested receivers...
15282        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15283                 == 0) {
15284            receivers = collectReceiverComponents(intent, resolvedType, users);
15285        }
15286        if (intent.getComponent() == null) {
15287            registeredReceivers = mReceiverResolver.queryIntent(intent,
15288                    resolvedType, false, userId);
15289        }
15290
15291        final boolean replacePending =
15292                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15293
15294        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15295                + " replacePending=" + replacePending);
15296
15297        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15298        if (!ordered && NR > 0) {
15299            // If we are not serializing this broadcast, then send the
15300            // registered receivers separately so they don't wait for the
15301            // components to be launched.
15302            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15303            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15304                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15305                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15306                    ordered, sticky, false, userId);
15307            if (DEBUG_BROADCAST) Slog.v(
15308                    TAG, "Enqueueing parallel broadcast " + r);
15309            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15310            if (!replaced) {
15311                queue.enqueueParallelBroadcastLocked(r);
15312                queue.scheduleBroadcastsLocked();
15313            }
15314            registeredReceivers = null;
15315            NR = 0;
15316        }
15317
15318        // Merge into one list.
15319        int ir = 0;
15320        if (receivers != null) {
15321            // A special case for PACKAGE_ADDED: do not allow the package
15322            // being added to see this broadcast.  This prevents them from
15323            // using this as a back door to get run as soon as they are
15324            // installed.  Maybe in the future we want to have a special install
15325            // broadcast or such for apps, but we'd like to deliberately make
15326            // this decision.
15327            String skipPackages[] = null;
15328            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15329                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15330                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15331                Uri data = intent.getData();
15332                if (data != null) {
15333                    String pkgName = data.getSchemeSpecificPart();
15334                    if (pkgName != null) {
15335                        skipPackages = new String[] { pkgName };
15336                    }
15337                }
15338            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15339                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15340            }
15341            if (skipPackages != null && (skipPackages.length > 0)) {
15342                for (String skipPackage : skipPackages) {
15343                    if (skipPackage != null) {
15344                        int NT = receivers.size();
15345                        for (int it=0; it<NT; it++) {
15346                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15347                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15348                                receivers.remove(it);
15349                                it--;
15350                                NT--;
15351                            }
15352                        }
15353                    }
15354                }
15355            }
15356
15357            int NT = receivers != null ? receivers.size() : 0;
15358            int it = 0;
15359            ResolveInfo curt = null;
15360            BroadcastFilter curr = null;
15361            while (it < NT && ir < NR) {
15362                if (curt == null) {
15363                    curt = (ResolveInfo)receivers.get(it);
15364                }
15365                if (curr == null) {
15366                    curr = registeredReceivers.get(ir);
15367                }
15368                if (curr.getPriority() >= curt.priority) {
15369                    // Insert this broadcast record into the final list.
15370                    receivers.add(it, curr);
15371                    ir++;
15372                    curr = null;
15373                    it++;
15374                    NT++;
15375                } else {
15376                    // Skip to the next ResolveInfo in the final list.
15377                    it++;
15378                    curt = null;
15379                }
15380            }
15381        }
15382        while (ir < NR) {
15383            if (receivers == null) {
15384                receivers = new ArrayList();
15385            }
15386            receivers.add(registeredReceivers.get(ir));
15387            ir++;
15388        }
15389
15390        if ((receivers != null && receivers.size() > 0)
15391                || resultTo != null) {
15392            BroadcastQueue queue = broadcastQueueForIntent(intent);
15393            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15394                    callerPackage, callingPid, callingUid, resolvedType,
15395                    requiredPermission, appOp, receivers, resultTo, resultCode,
15396                    resultData, map, ordered, sticky, false, userId);
15397            if (DEBUG_BROADCAST) Slog.v(
15398                    TAG, "Enqueueing ordered broadcast " + r
15399                    + ": prev had " + queue.mOrderedBroadcasts.size());
15400            if (DEBUG_BROADCAST) {
15401                int seq = r.intent.getIntExtra("seq", -1);
15402                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15403            }
15404            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15405            if (!replaced) {
15406                queue.enqueueOrderedBroadcastLocked(r);
15407                queue.scheduleBroadcastsLocked();
15408            }
15409        }
15410
15411        return ActivityManager.BROADCAST_SUCCESS;
15412    }
15413
15414    final Intent verifyBroadcastLocked(Intent intent) {
15415        // Refuse possible leaked file descriptors
15416        if (intent != null && intent.hasFileDescriptors() == true) {
15417            throw new IllegalArgumentException("File descriptors passed in Intent");
15418        }
15419
15420        int flags = intent.getFlags();
15421
15422        if (!mProcessesReady) {
15423            // if the caller really truly claims to know what they're doing, go
15424            // ahead and allow the broadcast without launching any receivers
15425            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15426                intent = new Intent(intent);
15427                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15428            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15429                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15430                        + " before boot completion");
15431                throw new IllegalStateException("Cannot broadcast before boot completed");
15432            }
15433        }
15434
15435        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15436            throw new IllegalArgumentException(
15437                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15438        }
15439
15440        return intent;
15441    }
15442
15443    public final int broadcastIntent(IApplicationThread caller,
15444            Intent intent, String resolvedType, IIntentReceiver resultTo,
15445            int resultCode, String resultData, Bundle map,
15446            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15447        enforceNotIsolatedCaller("broadcastIntent");
15448        synchronized(this) {
15449            intent = verifyBroadcastLocked(intent);
15450
15451            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15452            final int callingPid = Binder.getCallingPid();
15453            final int callingUid = Binder.getCallingUid();
15454            final long origId = Binder.clearCallingIdentity();
15455            int res = broadcastIntentLocked(callerApp,
15456                    callerApp != null ? callerApp.info.packageName : null,
15457                    intent, resolvedType, resultTo,
15458                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15459                    callingPid, callingUid, userId);
15460            Binder.restoreCallingIdentity(origId);
15461            return res;
15462        }
15463    }
15464
15465    int broadcastIntentInPackage(String packageName, int uid,
15466            Intent intent, String resolvedType, IIntentReceiver resultTo,
15467            int resultCode, String resultData, Bundle map,
15468            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15469        synchronized(this) {
15470            intent = verifyBroadcastLocked(intent);
15471
15472            final long origId = Binder.clearCallingIdentity();
15473            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15474                    resultTo, resultCode, resultData, map, requiredPermission,
15475                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15476            Binder.restoreCallingIdentity(origId);
15477            return res;
15478        }
15479    }
15480
15481    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15482        // Refuse possible leaked file descriptors
15483        if (intent != null && intent.hasFileDescriptors() == true) {
15484            throw new IllegalArgumentException("File descriptors passed in Intent");
15485        }
15486
15487        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15488                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15489
15490        synchronized(this) {
15491            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15492                    != PackageManager.PERMISSION_GRANTED) {
15493                String msg = "Permission Denial: unbroadcastIntent() from pid="
15494                        + Binder.getCallingPid()
15495                        + ", uid=" + Binder.getCallingUid()
15496                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15497                Slog.w(TAG, msg);
15498                throw new SecurityException(msg);
15499            }
15500            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15501            if (stickies != null) {
15502                ArrayList<Intent> list = stickies.get(intent.getAction());
15503                if (list != null) {
15504                    int N = list.size();
15505                    int i;
15506                    for (i=0; i<N; i++) {
15507                        if (intent.filterEquals(list.get(i))) {
15508                            list.remove(i);
15509                            break;
15510                        }
15511                    }
15512                    if (list.size() <= 0) {
15513                        stickies.remove(intent.getAction());
15514                    }
15515                }
15516                if (stickies.size() <= 0) {
15517                    mStickyBroadcasts.remove(userId);
15518                }
15519            }
15520        }
15521    }
15522
15523    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15524            String resultData, Bundle resultExtras, boolean resultAbort) {
15525        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15526        if (r == null) {
15527            Slog.w(TAG, "finishReceiver called but not found on queue");
15528            return false;
15529        }
15530
15531        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15532    }
15533
15534    void backgroundServicesFinishedLocked(int userId) {
15535        for (BroadcastQueue queue : mBroadcastQueues) {
15536            queue.backgroundServicesFinishedLocked(userId);
15537        }
15538    }
15539
15540    public void finishReceiver(IBinder who, int resultCode, String resultData,
15541            Bundle resultExtras, boolean resultAbort) {
15542        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15543
15544        // Refuse possible leaked file descriptors
15545        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15546            throw new IllegalArgumentException("File descriptors passed in Bundle");
15547        }
15548
15549        final long origId = Binder.clearCallingIdentity();
15550        try {
15551            boolean doNext = false;
15552            BroadcastRecord r;
15553
15554            synchronized(this) {
15555                r = broadcastRecordForReceiverLocked(who);
15556                if (r != null) {
15557                    doNext = r.queue.finishReceiverLocked(r, resultCode,
15558                        resultData, resultExtras, resultAbort, true);
15559                }
15560            }
15561
15562            if (doNext) {
15563                r.queue.processNextBroadcast(false);
15564            }
15565            trimApplications();
15566        } finally {
15567            Binder.restoreCallingIdentity(origId);
15568        }
15569    }
15570
15571    // =========================================================
15572    // INSTRUMENTATION
15573    // =========================================================
15574
15575    public boolean startInstrumentation(ComponentName className,
15576            String profileFile, int flags, Bundle arguments,
15577            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
15578            int userId, String abiOverride) {
15579        enforceNotIsolatedCaller("startInstrumentation");
15580        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15581                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
15582        // Refuse possible leaked file descriptors
15583        if (arguments != null && arguments.hasFileDescriptors()) {
15584            throw new IllegalArgumentException("File descriptors passed in Bundle");
15585        }
15586
15587        synchronized(this) {
15588            InstrumentationInfo ii = null;
15589            ApplicationInfo ai = null;
15590            try {
15591                ii = mContext.getPackageManager().getInstrumentationInfo(
15592                    className, STOCK_PM_FLAGS);
15593                ai = AppGlobals.getPackageManager().getApplicationInfo(
15594                        ii.targetPackage, STOCK_PM_FLAGS, userId);
15595            } catch (PackageManager.NameNotFoundException e) {
15596            } catch (RemoteException e) {
15597            }
15598            if (ii == null) {
15599                reportStartInstrumentationFailure(watcher, className,
15600                        "Unable to find instrumentation info for: " + className);
15601                return false;
15602            }
15603            if (ai == null) {
15604                reportStartInstrumentationFailure(watcher, className,
15605                        "Unable to find instrumentation target package: " + ii.targetPackage);
15606                return false;
15607            }
15608
15609            int match = mContext.getPackageManager().checkSignatures(
15610                    ii.targetPackage, ii.packageName);
15611            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15612                String msg = "Permission Denial: starting instrumentation "
15613                        + className + " from pid="
15614                        + Binder.getCallingPid()
15615                        + ", uid=" + Binder.getCallingPid()
15616                        + " not allowed because package " + ii.packageName
15617                        + " does not have a signature matching the target "
15618                        + ii.targetPackage;
15619                reportStartInstrumentationFailure(watcher, className, msg);
15620                throw new SecurityException(msg);
15621            }
15622
15623            final long origId = Binder.clearCallingIdentity();
15624            // Instrumentation can kill and relaunch even persistent processes
15625            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15626                    "start instr");
15627            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15628            app.instrumentationClass = className;
15629            app.instrumentationInfo = ai;
15630            app.instrumentationProfileFile = profileFile;
15631            app.instrumentationArguments = arguments;
15632            app.instrumentationWatcher = watcher;
15633            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15634            app.instrumentationResultClass = className;
15635            Binder.restoreCallingIdentity(origId);
15636        }
15637
15638        return true;
15639    }
15640
15641    /**
15642     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15643     * error to the logs, but if somebody is watching, send the report there too.  This enables
15644     * the "am" command to report errors with more information.
15645     *
15646     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15647     * @param cn The component name of the instrumentation.
15648     * @param report The error report.
15649     */
15650    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
15651            ComponentName cn, String report) {
15652        Slog.w(TAG, report);
15653        try {
15654            if (watcher != null) {
15655                Bundle results = new Bundle();
15656                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
15657                results.putString("Error", report);
15658                watcher.instrumentationStatus(cn, -1, results);
15659            }
15660        } catch (RemoteException e) {
15661            Slog.w(TAG, e);
15662        }
15663    }
15664
15665    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
15666        if (app.instrumentationWatcher != null) {
15667            try {
15668                // NOTE:  IInstrumentationWatcher *must* be oneway here
15669                app.instrumentationWatcher.instrumentationFinished(
15670                    app.instrumentationClass,
15671                    resultCode,
15672                    results);
15673            } catch (RemoteException e) {
15674            }
15675        }
15676        if (app.instrumentationUiAutomationConnection != null) {
15677            try {
15678                app.instrumentationUiAutomationConnection.shutdown();
15679            } catch (RemoteException re) {
15680                /* ignore */
15681            }
15682            // Only a UiAutomation can set this flag and now that
15683            // it is finished we make sure it is reset to its default.
15684            mUserIsMonkey = false;
15685        }
15686        app.instrumentationWatcher = null;
15687        app.instrumentationUiAutomationConnection = null;
15688        app.instrumentationClass = null;
15689        app.instrumentationInfo = null;
15690        app.instrumentationProfileFile = null;
15691        app.instrumentationArguments = null;
15692
15693        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
15694                "finished inst");
15695    }
15696
15697    public void finishInstrumentation(IApplicationThread target,
15698            int resultCode, Bundle results) {
15699        int userId = UserHandle.getCallingUserId();
15700        // Refuse possible leaked file descriptors
15701        if (results != null && results.hasFileDescriptors()) {
15702            throw new IllegalArgumentException("File descriptors passed in Intent");
15703        }
15704
15705        synchronized(this) {
15706            ProcessRecord app = getRecordForAppLocked(target);
15707            if (app == null) {
15708                Slog.w(TAG, "finishInstrumentation: no app for " + target);
15709                return;
15710            }
15711            final long origId = Binder.clearCallingIdentity();
15712            finishInstrumentationLocked(app, resultCode, results);
15713            Binder.restoreCallingIdentity(origId);
15714        }
15715    }
15716
15717    // =========================================================
15718    // CONFIGURATION
15719    // =========================================================
15720
15721    public ConfigurationInfo getDeviceConfigurationInfo() {
15722        ConfigurationInfo config = new ConfigurationInfo();
15723        synchronized (this) {
15724            config.reqTouchScreen = mConfiguration.touchscreen;
15725            config.reqKeyboardType = mConfiguration.keyboard;
15726            config.reqNavigation = mConfiguration.navigation;
15727            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
15728                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
15729                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
15730            }
15731            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
15732                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
15733                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
15734            }
15735            config.reqGlEsVersion = GL_ES_VERSION;
15736        }
15737        return config;
15738    }
15739
15740    ActivityStack getFocusedStack() {
15741        return mStackSupervisor.getFocusedStack();
15742    }
15743
15744    public Configuration getConfiguration() {
15745        Configuration ci;
15746        synchronized(this) {
15747            ci = new Configuration(mConfiguration);
15748        }
15749        return ci;
15750    }
15751
15752    public void updatePersistentConfiguration(Configuration values) {
15753        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15754                "updateConfiguration()");
15755        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
15756                "updateConfiguration()");
15757        if (values == null) {
15758            throw new NullPointerException("Configuration must not be null");
15759        }
15760
15761        synchronized(this) {
15762            final long origId = Binder.clearCallingIdentity();
15763            updateConfigurationLocked(values, null, true, false);
15764            Binder.restoreCallingIdentity(origId);
15765        }
15766    }
15767
15768    public void updateConfiguration(Configuration values) {
15769        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15770                "updateConfiguration()");
15771
15772        synchronized(this) {
15773            if (values == null && mWindowManager != null) {
15774                // sentinel: fetch the current configuration from the window manager
15775                values = mWindowManager.computeNewConfiguration();
15776            }
15777
15778            if (mWindowManager != null) {
15779                mProcessList.applyDisplaySize(mWindowManager);
15780            }
15781
15782            final long origId = Binder.clearCallingIdentity();
15783            if (values != null) {
15784                Settings.System.clearConfiguration(values);
15785            }
15786            updateConfigurationLocked(values, null, false, false);
15787            Binder.restoreCallingIdentity(origId);
15788        }
15789    }
15790
15791    /**
15792     * Do either or both things: (1) change the current configuration, and (2)
15793     * make sure the given activity is running with the (now) current
15794     * configuration.  Returns true if the activity has been left running, or
15795     * false if <var>starting</var> is being destroyed to match the new
15796     * configuration.
15797     * @param persistent TODO
15798     */
15799    boolean updateConfigurationLocked(Configuration values,
15800            ActivityRecord starting, boolean persistent, boolean initLocale) {
15801        int changes = 0;
15802
15803        if (values != null) {
15804            Configuration newConfig = new Configuration(mConfiguration);
15805            changes = newConfig.updateFrom(values);
15806            if (changes != 0) {
15807                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
15808                    Slog.i(TAG, "Updating configuration to: " + values);
15809                }
15810
15811                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15812
15813                if (values.locale != null && !initLocale) {
15814                    saveLocaleLocked(values.locale,
15815                                     !values.locale.equals(mConfiguration.locale),
15816                                     values.userSetLocale);
15817                }
15818
15819                mConfigurationSeq++;
15820                if (mConfigurationSeq <= 0) {
15821                    mConfigurationSeq = 1;
15822                }
15823                newConfig.seq = mConfigurationSeq;
15824                mConfiguration = newConfig;
15825                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15826                //mUsageStatsService.noteStartConfig(newConfig);
15827
15828                final Configuration configCopy = new Configuration(mConfiguration);
15829
15830                // TODO: If our config changes, should we auto dismiss any currently
15831                // showing dialogs?
15832                mShowDialogs = shouldShowDialogs(newConfig);
15833
15834                AttributeCache ac = AttributeCache.instance();
15835                if (ac != null) {
15836                    ac.updateConfiguration(configCopy);
15837                }
15838
15839                // Make sure all resources in our process are updated
15840                // right now, so that anyone who is going to retrieve
15841                // resource values after we return will be sure to get
15842                // the new ones.  This is especially important during
15843                // boot, where the first config change needs to guarantee
15844                // all resources have that config before following boot
15845                // code is executed.
15846                mSystemThread.applyConfigurationToResources(configCopy);
15847
15848                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15849                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15850                    msg.obj = new Configuration(configCopy);
15851                    mHandler.sendMessage(msg);
15852                }
15853
15854                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15855                    ProcessRecord app = mLruProcesses.get(i);
15856                    try {
15857                        if (app.thread != null) {
15858                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15859                                    + app.processName + " new config " + mConfiguration);
15860                            app.thread.scheduleConfigurationChanged(configCopy);
15861                        }
15862                    } catch (Exception e) {
15863                    }
15864                }
15865                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15866                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15867                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15868                        | Intent.FLAG_RECEIVER_FOREGROUND);
15869                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15870                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15871                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15872                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
15873                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
15874                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15875                    broadcastIntentLocked(null, null, intent,
15876                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15877                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
15878                }
15879            }
15880        }
15881
15882        boolean kept = true;
15883        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
15884        // mainStack is null during startup.
15885        if (mainStack != null) {
15886            if (changes != 0 && starting == null) {
15887                // If the configuration changed, and the caller is not already
15888                // in the process of starting an activity, then find the top
15889                // activity to check if its configuration needs to change.
15890                starting = mainStack.topRunningActivityLocked(null);
15891            }
15892
15893            if (starting != null) {
15894                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
15895                // And we need to make sure at this point that all other activities
15896                // are made visible with the correct configuration.
15897                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
15898            }
15899        }
15900
15901        if (values != null && mWindowManager != null) {
15902            mWindowManager.setNewConfiguration(mConfiguration);
15903        }
15904
15905        return kept;
15906    }
15907
15908    /**
15909     * Decide based on the configuration whether we should shouw the ANR,
15910     * crash, etc dialogs.  The idea is that if there is no affordnace to
15911     * press the on-screen buttons, we shouldn't show the dialog.
15912     *
15913     * A thought: SystemUI might also want to get told about this, the Power
15914     * dialog / global actions also might want different behaviors.
15915     */
15916    private static final boolean shouldShowDialogs(Configuration config) {
15917        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
15918                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
15919    }
15920
15921    /**
15922     * Save the locale.  You must be inside a synchronized (this) block.
15923     */
15924    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
15925        if(isDiff) {
15926            SystemProperties.set("user.language", l.getLanguage());
15927            SystemProperties.set("user.region", l.getCountry());
15928        }
15929
15930        if(isPersist) {
15931            SystemProperties.set("persist.sys.language", l.getLanguage());
15932            SystemProperties.set("persist.sys.country", l.getCountry());
15933            SystemProperties.set("persist.sys.localevar", l.getVariant());
15934        }
15935    }
15936
15937    @Override
15938    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
15939        synchronized (this) {
15940            ActivityRecord srec = ActivityRecord.forToken(token);
15941            if (srec.task != null && srec.task.stack != null) {
15942                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
15943            }
15944        }
15945        return false;
15946    }
15947
15948    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
15949            Intent resultData) {
15950
15951        synchronized (this) {
15952            final ActivityStack stack = ActivityRecord.getStackLocked(token);
15953            if (stack != null) {
15954                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
15955            }
15956            return false;
15957        }
15958    }
15959
15960    public int getLaunchedFromUid(IBinder activityToken) {
15961        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15962        if (srec == null) {
15963            return -1;
15964        }
15965        return srec.launchedFromUid;
15966    }
15967
15968    public String getLaunchedFromPackage(IBinder activityToken) {
15969        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15970        if (srec == null) {
15971            return null;
15972        }
15973        return srec.launchedFromPackage;
15974    }
15975
15976    // =========================================================
15977    // LIFETIME MANAGEMENT
15978    // =========================================================
15979
15980    // Returns which broadcast queue the app is the current [or imminent] receiver
15981    // on, or 'null' if the app is not an active broadcast recipient.
15982    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
15983        BroadcastRecord r = app.curReceiver;
15984        if (r != null) {
15985            return r.queue;
15986        }
15987
15988        // It's not the current receiver, but it might be starting up to become one
15989        synchronized (this) {
15990            for (BroadcastQueue queue : mBroadcastQueues) {
15991                r = queue.mPendingBroadcast;
15992                if (r != null && r.curApp == app) {
15993                    // found it; report which queue it's in
15994                    return queue;
15995                }
15996            }
15997        }
15998
15999        return null;
16000    }
16001
16002    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16003            boolean doingAll, long now) {
16004        if (mAdjSeq == app.adjSeq) {
16005            // This adjustment has already been computed.
16006            return app.curRawAdj;
16007        }
16008
16009        if (app.thread == null) {
16010            app.adjSeq = mAdjSeq;
16011            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16012            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16013            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16014        }
16015
16016        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16017        app.adjSource = null;
16018        app.adjTarget = null;
16019        app.empty = false;
16020        app.cached = false;
16021
16022        final int activitiesSize = app.activities.size();
16023
16024        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16025            // The max adjustment doesn't allow this app to be anything
16026            // below foreground, so it is not worth doing work for it.
16027            app.adjType = "fixed";
16028            app.adjSeq = mAdjSeq;
16029            app.curRawAdj = app.maxAdj;
16030            app.foregroundActivities = false;
16031            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16032            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16033            // System processes can do UI, and when they do we want to have
16034            // them trim their memory after the user leaves the UI.  To
16035            // facilitate this, here we need to determine whether or not it
16036            // is currently showing UI.
16037            app.systemNoUi = true;
16038            if (app == TOP_APP) {
16039                app.systemNoUi = false;
16040            } else if (activitiesSize > 0) {
16041                for (int j = 0; j < activitiesSize; j++) {
16042                    final ActivityRecord r = app.activities.get(j);
16043                    if (r.visible) {
16044                        app.systemNoUi = false;
16045                    }
16046                }
16047            }
16048            if (!app.systemNoUi) {
16049                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16050            }
16051            return (app.curAdj=app.maxAdj);
16052        }
16053
16054        app.systemNoUi = false;
16055
16056        // Determine the importance of the process, starting with most
16057        // important to least, and assign an appropriate OOM adjustment.
16058        int adj;
16059        int schedGroup;
16060        int procState;
16061        boolean foregroundActivities = false;
16062        BroadcastQueue queue;
16063        if (app == TOP_APP) {
16064            // The last app on the list is the foreground app.
16065            adj = ProcessList.FOREGROUND_APP_ADJ;
16066            schedGroup = Process.THREAD_GROUP_DEFAULT;
16067            app.adjType = "top-activity";
16068            foregroundActivities = true;
16069            procState = ActivityManager.PROCESS_STATE_TOP;
16070        } else if (app.instrumentationClass != null) {
16071            // Don't want to kill running instrumentation.
16072            adj = ProcessList.FOREGROUND_APP_ADJ;
16073            schedGroup = Process.THREAD_GROUP_DEFAULT;
16074            app.adjType = "instrumentation";
16075            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16076        } else if ((queue = isReceivingBroadcast(app)) != null) {
16077            // An app that is currently receiving a broadcast also
16078            // counts as being in the foreground for OOM killer purposes.
16079            // It's placed in a sched group based on the nature of the
16080            // broadcast as reflected by which queue it's active in.
16081            adj = ProcessList.FOREGROUND_APP_ADJ;
16082            schedGroup = (queue == mFgBroadcastQueue)
16083                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16084            app.adjType = "broadcast";
16085            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16086        } else if (app.executingServices.size() > 0) {
16087            // An app that is currently executing a service callback also
16088            // counts as being in the foreground.
16089            adj = ProcessList.FOREGROUND_APP_ADJ;
16090            schedGroup = app.execServicesFg ?
16091                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16092            app.adjType = "exec-service";
16093            procState = ActivityManager.PROCESS_STATE_SERVICE;
16094            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16095        } else {
16096            // As far as we know the process is empty.  We may change our mind later.
16097            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16098            // At this point we don't actually know the adjustment.  Use the cached adj
16099            // value that the caller wants us to.
16100            adj = cachedAdj;
16101            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16102            app.cached = true;
16103            app.empty = true;
16104            app.adjType = "cch-empty";
16105        }
16106
16107        // Examine all activities if not already foreground.
16108        if (!foregroundActivities && activitiesSize > 0) {
16109            for (int j = 0; j < activitiesSize; j++) {
16110                final ActivityRecord r = app.activities.get(j);
16111                if (r.app != app) {
16112                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16113                            + app + "?!?");
16114                    continue;
16115                }
16116                if (r.visible) {
16117                    // App has a visible activity; only upgrade adjustment.
16118                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16119                        adj = ProcessList.VISIBLE_APP_ADJ;
16120                        app.adjType = "visible";
16121                    }
16122                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16123                        procState = ActivityManager.PROCESS_STATE_TOP;
16124                    }
16125                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16126                    app.cached = false;
16127                    app.empty = false;
16128                    foregroundActivities = true;
16129                    break;
16130                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16131                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16132                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16133                        app.adjType = "pausing";
16134                    }
16135                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16136                        procState = ActivityManager.PROCESS_STATE_TOP;
16137                    }
16138                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16139                    app.cached = false;
16140                    app.empty = false;
16141                    foregroundActivities = true;
16142                } else if (r.state == ActivityState.STOPPING) {
16143                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16144                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16145                        app.adjType = "stopping";
16146                    }
16147                    // For the process state, we will at this point consider the
16148                    // process to be cached.  It will be cached either as an activity
16149                    // or empty depending on whether the activity is finishing.  We do
16150                    // this so that we can treat the process as cached for purposes of
16151                    // memory trimming (determing current memory level, trim command to
16152                    // send to process) since there can be an arbitrary number of stopping
16153                    // processes and they should soon all go into the cached state.
16154                    if (!r.finishing) {
16155                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16156                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16157                        }
16158                    }
16159                    app.cached = false;
16160                    app.empty = false;
16161                    foregroundActivities = true;
16162                } else {
16163                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16164                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16165                        app.adjType = "cch-act";
16166                    }
16167                }
16168            }
16169        }
16170
16171        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16172            if (app.foregroundServices) {
16173                // The user is aware of this app, so make it visible.
16174                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16175                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16176                app.cached = false;
16177                app.adjType = "fg-service";
16178                schedGroup = Process.THREAD_GROUP_DEFAULT;
16179            } else if (app.forcingToForeground != null) {
16180                // The user is aware of this app, so make it visible.
16181                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16182                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16183                app.cached = false;
16184                app.adjType = "force-fg";
16185                app.adjSource = app.forcingToForeground;
16186                schedGroup = Process.THREAD_GROUP_DEFAULT;
16187            }
16188        }
16189
16190        if (app == mHeavyWeightProcess) {
16191            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16192                // We don't want to kill the current heavy-weight process.
16193                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16194                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16195                app.cached = false;
16196                app.adjType = "heavy";
16197            }
16198            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16199                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16200            }
16201        }
16202
16203        if (app == mHomeProcess) {
16204            if (adj > ProcessList.HOME_APP_ADJ) {
16205                // This process is hosting what we currently consider to be the
16206                // home app, so we don't want to let it go into the background.
16207                adj = ProcessList.HOME_APP_ADJ;
16208                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16209                app.cached = false;
16210                app.adjType = "home";
16211            }
16212            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16213                procState = ActivityManager.PROCESS_STATE_HOME;
16214            }
16215        }
16216
16217        if (app == mPreviousProcess && app.activities.size() > 0) {
16218            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16219                // This was the previous process that showed UI to the user.
16220                // We want to try to keep it around more aggressively, to give
16221                // a good experience around switching between two apps.
16222                adj = ProcessList.PREVIOUS_APP_ADJ;
16223                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16224                app.cached = false;
16225                app.adjType = "previous";
16226            }
16227            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16228                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16229            }
16230        }
16231
16232        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16233                + " reason=" + app.adjType);
16234
16235        // By default, we use the computed adjustment.  It may be changed if
16236        // there are applications dependent on our services or providers, but
16237        // this gives us a baseline and makes sure we don't get into an
16238        // infinite recursion.
16239        app.adjSeq = mAdjSeq;
16240        app.curRawAdj = adj;
16241        app.hasStartedServices = false;
16242
16243        if (mBackupTarget != null && app == mBackupTarget.app) {
16244            // If possible we want to avoid killing apps while they're being backed up
16245            if (adj > ProcessList.BACKUP_APP_ADJ) {
16246                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16247                adj = ProcessList.BACKUP_APP_ADJ;
16248                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16249                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16250                }
16251                app.adjType = "backup";
16252                app.cached = false;
16253            }
16254            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16255                procState = ActivityManager.PROCESS_STATE_BACKUP;
16256            }
16257        }
16258
16259        boolean mayBeTop = false;
16260
16261        for (int is = app.services.size()-1;
16262                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16263                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16264                        || procState > ActivityManager.PROCESS_STATE_TOP);
16265                is--) {
16266            ServiceRecord s = app.services.valueAt(is);
16267            if (s.startRequested) {
16268                app.hasStartedServices = true;
16269                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16270                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16271                }
16272                if (app.hasShownUi && app != mHomeProcess) {
16273                    // If this process has shown some UI, let it immediately
16274                    // go to the LRU list because it may be pretty heavy with
16275                    // UI stuff.  We'll tag it with a label just to help
16276                    // debug and understand what is going on.
16277                    if (adj > ProcessList.SERVICE_ADJ) {
16278                        app.adjType = "cch-started-ui-services";
16279                    }
16280                } else {
16281                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16282                        // This service has seen some activity within
16283                        // recent memory, so we will keep its process ahead
16284                        // of the background processes.
16285                        if (adj > ProcessList.SERVICE_ADJ) {
16286                            adj = ProcessList.SERVICE_ADJ;
16287                            app.adjType = "started-services";
16288                            app.cached = false;
16289                        }
16290                    }
16291                    // If we have let the service slide into the background
16292                    // state, still have some text describing what it is doing
16293                    // even though the service no longer has an impact.
16294                    if (adj > ProcessList.SERVICE_ADJ) {
16295                        app.adjType = "cch-started-services";
16296                    }
16297                }
16298            }
16299            for (int conni = s.connections.size()-1;
16300                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16301                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16302                            || procState > ActivityManager.PROCESS_STATE_TOP);
16303                    conni--) {
16304                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16305                for (int i = 0;
16306                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16307                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16308                                || procState > ActivityManager.PROCESS_STATE_TOP);
16309                        i++) {
16310                    // XXX should compute this based on the max of
16311                    // all connected clients.
16312                    ConnectionRecord cr = clist.get(i);
16313                    if (cr.binding.client == app) {
16314                        // Binding to ourself is not interesting.
16315                        continue;
16316                    }
16317                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16318                        ProcessRecord client = cr.binding.client;
16319                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16320                                TOP_APP, doingAll, now);
16321                        int clientProcState = client.curProcState;
16322                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16323                            // If the other app is cached for any reason, for purposes here
16324                            // we are going to consider it empty.  The specific cached state
16325                            // doesn't propagate except under certain conditions.
16326                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16327                        }
16328                        String adjType = null;
16329                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16330                            // Not doing bind OOM management, so treat
16331                            // this guy more like a started service.
16332                            if (app.hasShownUi && app != mHomeProcess) {
16333                                // If this process has shown some UI, let it immediately
16334                                // go to the LRU list because it may be pretty heavy with
16335                                // UI stuff.  We'll tag it with a label just to help
16336                                // debug and understand what is going on.
16337                                if (adj > clientAdj) {
16338                                    adjType = "cch-bound-ui-services";
16339                                }
16340                                app.cached = false;
16341                                clientAdj = adj;
16342                                clientProcState = procState;
16343                            } else {
16344                                if (now >= (s.lastActivity
16345                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16346                                    // This service has not seen activity within
16347                                    // recent memory, so allow it to drop to the
16348                                    // LRU list if there is no other reason to keep
16349                                    // it around.  We'll also tag it with a label just
16350                                    // to help debug and undertand what is going on.
16351                                    if (adj > clientAdj) {
16352                                        adjType = "cch-bound-services";
16353                                    }
16354                                    clientAdj = adj;
16355                                }
16356                            }
16357                        }
16358                        if (adj > clientAdj) {
16359                            // If this process has recently shown UI, and
16360                            // the process that is binding to it is less
16361                            // important than being visible, then we don't
16362                            // care about the binding as much as we care
16363                            // about letting this process get into the LRU
16364                            // list to be killed and restarted if needed for
16365                            // memory.
16366                            if (app.hasShownUi && app != mHomeProcess
16367                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16368                                adjType = "cch-bound-ui-services";
16369                            } else {
16370                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16371                                        |Context.BIND_IMPORTANT)) != 0) {
16372                                    adj = clientAdj;
16373                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16374                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16375                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16376                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16377                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16378                                    adj = clientAdj;
16379                                } else {
16380                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16381                                        adj = ProcessList.VISIBLE_APP_ADJ;
16382                                    }
16383                                }
16384                                if (!client.cached) {
16385                                    app.cached = false;
16386                                }
16387                                adjType = "service";
16388                            }
16389                        }
16390                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16391                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16392                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16393                            }
16394                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16395                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16396                                    // Special handling of clients who are in the top state.
16397                                    // We *may* want to consider this process to be in the
16398                                    // top state as well, but only if there is not another
16399                                    // reason for it to be running.  Being on the top is a
16400                                    // special state, meaning you are specifically running
16401                                    // for the current top app.  If the process is already
16402                                    // running in the background for some other reason, it
16403                                    // is more important to continue considering it to be
16404                                    // in the background state.
16405                                    mayBeTop = true;
16406                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16407                                } else {
16408                                    // Special handling for above-top states (persistent
16409                                    // processes).  These should not bring the current process
16410                                    // into the top state, since they are not on top.  Instead
16411                                    // give them the best state after that.
16412                                    clientProcState =
16413                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16414                                }
16415                            }
16416                        } else {
16417                            if (clientProcState <
16418                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16419                                clientProcState =
16420                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16421                            }
16422                        }
16423                        if (procState > clientProcState) {
16424                            procState = clientProcState;
16425                        }
16426                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16427                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16428                            app.pendingUiClean = true;
16429                        }
16430                        if (adjType != null) {
16431                            app.adjType = adjType;
16432                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16433                                    .REASON_SERVICE_IN_USE;
16434                            app.adjSource = cr.binding.client;
16435                            app.adjSourceProcState = clientProcState;
16436                            app.adjTarget = s.name;
16437                        }
16438                    }
16439                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16440                        app.treatLikeActivity = true;
16441                    }
16442                    final ActivityRecord a = cr.activity;
16443                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16444                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16445                                (a.visible || a.state == ActivityState.RESUMED
16446                                 || a.state == ActivityState.PAUSING)) {
16447                            adj = ProcessList.FOREGROUND_APP_ADJ;
16448                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16449                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16450                            }
16451                            app.cached = false;
16452                            app.adjType = "service";
16453                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16454                                    .REASON_SERVICE_IN_USE;
16455                            app.adjSource = a;
16456                            app.adjSourceProcState = procState;
16457                            app.adjTarget = s.name;
16458                        }
16459                    }
16460                }
16461            }
16462        }
16463
16464        for (int provi = app.pubProviders.size()-1;
16465                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16466                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16467                        || procState > ActivityManager.PROCESS_STATE_TOP);
16468                provi--) {
16469            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16470            for (int i = cpr.connections.size()-1;
16471                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16472                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16473                            || procState > ActivityManager.PROCESS_STATE_TOP);
16474                    i--) {
16475                ContentProviderConnection conn = cpr.connections.get(i);
16476                ProcessRecord client = conn.client;
16477                if (client == app) {
16478                    // Being our own client is not interesting.
16479                    continue;
16480                }
16481                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16482                int clientProcState = client.curProcState;
16483                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16484                    // If the other app is cached for any reason, for purposes here
16485                    // we are going to consider it empty.
16486                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16487                }
16488                if (adj > clientAdj) {
16489                    if (app.hasShownUi && app != mHomeProcess
16490                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16491                        app.adjType = "cch-ui-provider";
16492                    } else {
16493                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16494                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16495                        app.adjType = "provider";
16496                    }
16497                    app.cached &= client.cached;
16498                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16499                            .REASON_PROVIDER_IN_USE;
16500                    app.adjSource = client;
16501                    app.adjSourceProcState = clientProcState;
16502                    app.adjTarget = cpr.name;
16503                }
16504                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16505                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16506                        // Special handling of clients who are in the top state.
16507                        // We *may* want to consider this process to be in the
16508                        // top state as well, but only if there is not another
16509                        // reason for it to be running.  Being on the top is a
16510                        // special state, meaning you are specifically running
16511                        // for the current top app.  If the process is already
16512                        // running in the background for some other reason, it
16513                        // is more important to continue considering it to be
16514                        // in the background state.
16515                        mayBeTop = true;
16516                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16517                    } else {
16518                        // Special handling for above-top states (persistent
16519                        // processes).  These should not bring the current process
16520                        // into the top state, since they are not on top.  Instead
16521                        // give them the best state after that.
16522                        clientProcState =
16523                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16524                    }
16525                }
16526                if (procState > clientProcState) {
16527                    procState = clientProcState;
16528                }
16529                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16530                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16531                }
16532            }
16533            // If the provider has external (non-framework) process
16534            // dependencies, ensure that its adjustment is at least
16535            // FOREGROUND_APP_ADJ.
16536            if (cpr.hasExternalProcessHandles()) {
16537                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16538                    adj = ProcessList.FOREGROUND_APP_ADJ;
16539                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16540                    app.cached = false;
16541                    app.adjType = "provider";
16542                    app.adjTarget = cpr.name;
16543                }
16544                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16545                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16546                }
16547            }
16548        }
16549
16550        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16551            // A client of one of our services or providers is in the top state.  We
16552            // *may* want to be in the top state, but not if we are already running in
16553            // the background for some other reason.  For the decision here, we are going
16554            // to pick out a few specific states that we want to remain in when a client
16555            // is top (states that tend to be longer-term) and otherwise allow it to go
16556            // to the top state.
16557            switch (procState) {
16558                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
16559                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
16560                case ActivityManager.PROCESS_STATE_SERVICE:
16561                    // These all are longer-term states, so pull them up to the top
16562                    // of the background states, but not all the way to the top state.
16563                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16564                    break;
16565                default:
16566                    // Otherwise, top is a better choice, so take it.
16567                    procState = ActivityManager.PROCESS_STATE_TOP;
16568                    break;
16569            }
16570        }
16571
16572        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
16573            if (app.hasClientActivities) {
16574                // This is a cached process, but with client activities.  Mark it so.
16575                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
16576                app.adjType = "cch-client-act";
16577            } else if (app.treatLikeActivity) {
16578                // This is a cached process, but somebody wants us to treat it like it has
16579                // an activity, okay!
16580                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16581                app.adjType = "cch-as-act";
16582            }
16583        }
16584
16585        if (adj == ProcessList.SERVICE_ADJ) {
16586            if (doingAll) {
16587                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
16588                mNewNumServiceProcs++;
16589                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
16590                if (!app.serviceb) {
16591                    // This service isn't far enough down on the LRU list to
16592                    // normally be a B service, but if we are low on RAM and it
16593                    // is large we want to force it down since we would prefer to
16594                    // keep launcher over it.
16595                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
16596                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
16597                        app.serviceHighRam = true;
16598                        app.serviceb = true;
16599                        //Slog.i(TAG, "ADJ " + app + " high ram!");
16600                    } else {
16601                        mNewNumAServiceProcs++;
16602                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
16603                    }
16604                } else {
16605                    app.serviceHighRam = false;
16606                }
16607            }
16608            if (app.serviceb) {
16609                adj = ProcessList.SERVICE_B_ADJ;
16610            }
16611        }
16612
16613        app.curRawAdj = adj;
16614
16615        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16616        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
16617        if (adj > app.maxAdj) {
16618            adj = app.maxAdj;
16619            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
16620                schedGroup = Process.THREAD_GROUP_DEFAULT;
16621            }
16622        }
16623
16624        // Do final modification to adj.  Everything we do between here and applying
16625        // the final setAdj must be done in this function, because we will also use
16626        // it when computing the final cached adj later.  Note that we don't need to
16627        // worry about this for max adj above, since max adj will always be used to
16628        // keep it out of the cached vaues.
16629        app.curAdj = app.modifyRawOomAdj(adj);
16630        app.curSchedGroup = schedGroup;
16631        app.curProcState = procState;
16632        app.foregroundActivities = foregroundActivities;
16633
16634        return app.curRawAdj;
16635    }
16636
16637    /**
16638     * Schedule PSS collection of a process.
16639     */
16640    void requestPssLocked(ProcessRecord proc, int procState) {
16641        if (mPendingPssProcesses.contains(proc)) {
16642            return;
16643        }
16644        if (mPendingPssProcesses.size() == 0) {
16645            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16646        }
16647        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
16648        proc.pssProcState = procState;
16649        mPendingPssProcesses.add(proc);
16650    }
16651
16652    /**
16653     * Schedule PSS collection of all processes.
16654     */
16655    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
16656        if (!always) {
16657            if (now < (mLastFullPssTime +
16658                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
16659                return;
16660            }
16661        }
16662        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
16663        mLastFullPssTime = now;
16664        mFullPssPending = true;
16665        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
16666        mPendingPssProcesses.clear();
16667        for (int i=mLruProcesses.size()-1; i>=0; i--) {
16668            ProcessRecord app = mLruProcesses.get(i);
16669            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
16670                app.pssProcState = app.setProcState;
16671                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16672                        isSleeping(), now);
16673                mPendingPssProcesses.add(app);
16674            }
16675        }
16676        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16677    }
16678
16679    /**
16680     * Ask a given process to GC right now.
16681     */
16682    final void performAppGcLocked(ProcessRecord app) {
16683        try {
16684            app.lastRequestedGc = SystemClock.uptimeMillis();
16685            if (app.thread != null) {
16686                if (app.reportLowMemory) {
16687                    app.reportLowMemory = false;
16688                    app.thread.scheduleLowMemory();
16689                } else {
16690                    app.thread.processInBackground();
16691                }
16692            }
16693        } catch (Exception e) {
16694            // whatever.
16695        }
16696    }
16697
16698    /**
16699     * Returns true if things are idle enough to perform GCs.
16700     */
16701    private final boolean canGcNowLocked() {
16702        boolean processingBroadcasts = false;
16703        for (BroadcastQueue q : mBroadcastQueues) {
16704            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
16705                processingBroadcasts = true;
16706            }
16707        }
16708        return !processingBroadcasts
16709                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
16710    }
16711
16712    /**
16713     * Perform GCs on all processes that are waiting for it, but only
16714     * if things are idle.
16715     */
16716    final void performAppGcsLocked() {
16717        final int N = mProcessesToGc.size();
16718        if (N <= 0) {
16719            return;
16720        }
16721        if (canGcNowLocked()) {
16722            while (mProcessesToGc.size() > 0) {
16723                ProcessRecord proc = mProcessesToGc.remove(0);
16724                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
16725                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
16726                            <= SystemClock.uptimeMillis()) {
16727                        // To avoid spamming the system, we will GC processes one
16728                        // at a time, waiting a few seconds between each.
16729                        performAppGcLocked(proc);
16730                        scheduleAppGcsLocked();
16731                        return;
16732                    } else {
16733                        // It hasn't been long enough since we last GCed this
16734                        // process...  put it in the list to wait for its time.
16735                        addProcessToGcListLocked(proc);
16736                        break;
16737                    }
16738                }
16739            }
16740
16741            scheduleAppGcsLocked();
16742        }
16743    }
16744
16745    /**
16746     * If all looks good, perform GCs on all processes waiting for them.
16747     */
16748    final void performAppGcsIfAppropriateLocked() {
16749        if (canGcNowLocked()) {
16750            performAppGcsLocked();
16751            return;
16752        }
16753        // Still not idle, wait some more.
16754        scheduleAppGcsLocked();
16755    }
16756
16757    /**
16758     * Schedule the execution of all pending app GCs.
16759     */
16760    final void scheduleAppGcsLocked() {
16761        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
16762
16763        if (mProcessesToGc.size() > 0) {
16764            // Schedule a GC for the time to the next process.
16765            ProcessRecord proc = mProcessesToGc.get(0);
16766            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
16767
16768            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
16769            long now = SystemClock.uptimeMillis();
16770            if (when < (now+GC_TIMEOUT)) {
16771                when = now + GC_TIMEOUT;
16772            }
16773            mHandler.sendMessageAtTime(msg, when);
16774        }
16775    }
16776
16777    /**
16778     * Add a process to the array of processes waiting to be GCed.  Keeps the
16779     * list in sorted order by the last GC time.  The process can't already be
16780     * on the list.
16781     */
16782    final void addProcessToGcListLocked(ProcessRecord proc) {
16783        boolean added = false;
16784        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
16785            if (mProcessesToGc.get(i).lastRequestedGc <
16786                    proc.lastRequestedGc) {
16787                added = true;
16788                mProcessesToGc.add(i+1, proc);
16789                break;
16790            }
16791        }
16792        if (!added) {
16793            mProcessesToGc.add(0, proc);
16794        }
16795    }
16796
16797    /**
16798     * Set up to ask a process to GC itself.  This will either do it
16799     * immediately, or put it on the list of processes to gc the next
16800     * time things are idle.
16801     */
16802    final void scheduleAppGcLocked(ProcessRecord app) {
16803        long now = SystemClock.uptimeMillis();
16804        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
16805            return;
16806        }
16807        if (!mProcessesToGc.contains(app)) {
16808            addProcessToGcListLocked(app);
16809            scheduleAppGcsLocked();
16810        }
16811    }
16812
16813    final void checkExcessivePowerUsageLocked(boolean doKills) {
16814        updateCpuStatsNow();
16815
16816        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16817        boolean doWakeKills = doKills;
16818        boolean doCpuKills = doKills;
16819        if (mLastPowerCheckRealtime == 0) {
16820            doWakeKills = false;
16821        }
16822        if (mLastPowerCheckUptime == 0) {
16823            doCpuKills = false;
16824        }
16825        if (stats.isScreenOn()) {
16826            doWakeKills = false;
16827        }
16828        final long curRealtime = SystemClock.elapsedRealtime();
16829        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16830        final long curUptime = SystemClock.uptimeMillis();
16831        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16832        mLastPowerCheckRealtime = curRealtime;
16833        mLastPowerCheckUptime = curUptime;
16834        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16835            doWakeKills = false;
16836        }
16837        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16838            doCpuKills = false;
16839        }
16840        int i = mLruProcesses.size();
16841        while (i > 0) {
16842            i--;
16843            ProcessRecord app = mLruProcesses.get(i);
16844            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16845                long wtime;
16846                synchronized (stats) {
16847                    wtime = stats.getProcessWakeTime(app.info.uid,
16848                            app.pid, curRealtime);
16849                }
16850                long wtimeUsed = wtime - app.lastWakeTime;
16851                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16852                if (DEBUG_POWER) {
16853                    StringBuilder sb = new StringBuilder(128);
16854                    sb.append("Wake for ");
16855                    app.toShortString(sb);
16856                    sb.append(": over ");
16857                    TimeUtils.formatDuration(realtimeSince, sb);
16858                    sb.append(" used ");
16859                    TimeUtils.formatDuration(wtimeUsed, sb);
16860                    sb.append(" (");
16861                    sb.append((wtimeUsed*100)/realtimeSince);
16862                    sb.append("%)");
16863                    Slog.i(TAG, sb.toString());
16864                    sb.setLength(0);
16865                    sb.append("CPU for ");
16866                    app.toShortString(sb);
16867                    sb.append(": over ");
16868                    TimeUtils.formatDuration(uptimeSince, sb);
16869                    sb.append(" used ");
16870                    TimeUtils.formatDuration(cputimeUsed, sb);
16871                    sb.append(" (");
16872                    sb.append((cputimeUsed*100)/uptimeSince);
16873                    sb.append("%)");
16874                    Slog.i(TAG, sb.toString());
16875                }
16876                // If a process has held a wake lock for more
16877                // than 50% of the time during this period,
16878                // that sounds bad.  Kill!
16879                if (doWakeKills && realtimeSince > 0
16880                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
16881                    synchronized (stats) {
16882                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
16883                                realtimeSince, wtimeUsed);
16884                    }
16885                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
16886                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
16887                } else if (doCpuKills && uptimeSince > 0
16888                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
16889                    synchronized (stats) {
16890                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
16891                                uptimeSince, cputimeUsed);
16892                    }
16893                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
16894                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
16895                } else {
16896                    app.lastWakeTime = wtime;
16897                    app.lastCpuTime = app.curCpuTime;
16898                }
16899            }
16900        }
16901    }
16902
16903    private final boolean applyOomAdjLocked(ProcessRecord app,
16904            ProcessRecord TOP_APP, boolean doingAll, long now) {
16905        boolean success = true;
16906
16907        if (app.curRawAdj != app.setRawAdj) {
16908            app.setRawAdj = app.curRawAdj;
16909        }
16910
16911        int changes = 0;
16912
16913        if (app.curAdj != app.setAdj) {
16914            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
16915            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
16916                TAG, "Set " + app.pid + " " + app.processName +
16917                " adj " + app.curAdj + ": " + app.adjType);
16918            app.setAdj = app.curAdj;
16919        }
16920
16921        if (app.setSchedGroup != app.curSchedGroup) {
16922            app.setSchedGroup = app.curSchedGroup;
16923            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16924                    "Setting process group of " + app.processName
16925                    + " to " + app.curSchedGroup);
16926            if (app.waitingToKill != null &&
16927                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
16928                app.kill(app.waitingToKill, true);
16929                success = false;
16930            } else {
16931                if (true) {
16932                    long oldId = Binder.clearCallingIdentity();
16933                    try {
16934                        Process.setProcessGroup(app.pid, app.curSchedGroup);
16935                    } catch (Exception e) {
16936                        Slog.w(TAG, "Failed setting process group of " + app.pid
16937                                + " to " + app.curSchedGroup);
16938                        e.printStackTrace();
16939                    } finally {
16940                        Binder.restoreCallingIdentity(oldId);
16941                    }
16942                } else {
16943                    if (app.thread != null) {
16944                        try {
16945                            app.thread.setSchedulingGroup(app.curSchedGroup);
16946                        } catch (RemoteException e) {
16947                        }
16948                    }
16949                }
16950                Process.setSwappiness(app.pid,
16951                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
16952            }
16953        }
16954        if (app.repForegroundActivities != app.foregroundActivities) {
16955            app.repForegroundActivities = app.foregroundActivities;
16956            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
16957        }
16958        if (app.repProcState != app.curProcState) {
16959            app.repProcState = app.curProcState;
16960            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
16961            if (app.thread != null) {
16962                try {
16963                    if (false) {
16964                        //RuntimeException h = new RuntimeException("here");
16965                        Slog.i(TAG, "Sending new process state " + app.repProcState
16966                                + " to " + app /*, h*/);
16967                    }
16968                    app.thread.setProcessState(app.repProcState);
16969                } catch (RemoteException e) {
16970                }
16971            }
16972        }
16973        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
16974                app.setProcState)) {
16975            app.lastStateTime = now;
16976            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16977                    isSleeping(), now);
16978            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
16979                    + ProcessList.makeProcStateString(app.setProcState) + " to "
16980                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
16981                    + (app.nextPssTime-now) + ": " + app);
16982        } else {
16983            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
16984                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
16985                requestPssLocked(app, app.setProcState);
16986                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
16987                        isSleeping(), now);
16988            } else if (false && DEBUG_PSS) {
16989                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
16990            }
16991        }
16992        if (app.setProcState != app.curProcState) {
16993            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16994                    "Proc state change of " + app.processName
16995                    + " to " + app.curProcState);
16996            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
16997            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
16998            if (setImportant && !curImportant) {
16999                // This app is no longer something we consider important enough to allow to
17000                // use arbitrary amounts of battery power.  Note
17001                // its current wake lock time to later know to kill it if
17002                // it is not behaving well.
17003                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17004                synchronized (stats) {
17005                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17006                            app.pid, SystemClock.elapsedRealtime());
17007                }
17008                app.lastCpuTime = app.curCpuTime;
17009
17010            }
17011            app.setProcState = app.curProcState;
17012            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17013                app.notCachedSinceIdle = false;
17014            }
17015            if (!doingAll) {
17016                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17017            } else {
17018                app.procStateChanged = true;
17019            }
17020        }
17021
17022        if (changes != 0) {
17023            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17024            int i = mPendingProcessChanges.size()-1;
17025            ProcessChangeItem item = null;
17026            while (i >= 0) {
17027                item = mPendingProcessChanges.get(i);
17028                if (item.pid == app.pid) {
17029                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17030                    break;
17031                }
17032                i--;
17033            }
17034            if (i < 0) {
17035                // No existing item in pending changes; need a new one.
17036                final int NA = mAvailProcessChanges.size();
17037                if (NA > 0) {
17038                    item = mAvailProcessChanges.remove(NA-1);
17039                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17040                } else {
17041                    item = new ProcessChangeItem();
17042                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17043                }
17044                item.changes = 0;
17045                item.pid = app.pid;
17046                item.uid = app.info.uid;
17047                if (mPendingProcessChanges.size() == 0) {
17048                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17049                            "*** Enqueueing dispatch processes changed!");
17050                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17051                }
17052                mPendingProcessChanges.add(item);
17053            }
17054            item.changes |= changes;
17055            item.processState = app.repProcState;
17056            item.foregroundActivities = app.repForegroundActivities;
17057            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17058                    + Integer.toHexString(System.identityHashCode(item))
17059                    + " " + app.toShortString() + ": changes=" + item.changes
17060                    + " procState=" + item.processState
17061                    + " foreground=" + item.foregroundActivities
17062                    + " type=" + app.adjType + " source=" + app.adjSource
17063                    + " target=" + app.adjTarget);
17064        }
17065
17066        return success;
17067    }
17068
17069    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17070        if (proc.thread != null) {
17071            if (proc.baseProcessTracker != null) {
17072                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17073            }
17074            if (proc.repProcState >= 0) {
17075                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17076                        proc.repProcState);
17077            }
17078        }
17079    }
17080
17081    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17082            ProcessRecord TOP_APP, boolean doingAll, long now) {
17083        if (app.thread == null) {
17084            return false;
17085        }
17086
17087        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17088
17089        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17090    }
17091
17092    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17093            boolean oomAdj) {
17094        if (isForeground != proc.foregroundServices) {
17095            proc.foregroundServices = isForeground;
17096            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17097                    proc.info.uid);
17098            if (isForeground) {
17099                if (curProcs == null) {
17100                    curProcs = new ArrayList<ProcessRecord>();
17101                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17102                }
17103                if (!curProcs.contains(proc)) {
17104                    curProcs.add(proc);
17105                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17106                            proc.info.packageName, proc.info.uid);
17107                }
17108            } else {
17109                if (curProcs != null) {
17110                    if (curProcs.remove(proc)) {
17111                        mBatteryStatsService.noteEvent(
17112                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17113                                proc.info.packageName, proc.info.uid);
17114                        if (curProcs.size() <= 0) {
17115                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17116                        }
17117                    }
17118                }
17119            }
17120            if (oomAdj) {
17121                updateOomAdjLocked();
17122            }
17123        }
17124    }
17125
17126    private final ActivityRecord resumedAppLocked() {
17127        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17128        String pkg;
17129        int uid;
17130        if (act != null) {
17131            pkg = act.packageName;
17132            uid = act.info.applicationInfo.uid;
17133        } else {
17134            pkg = null;
17135            uid = -1;
17136        }
17137        // Has the UID or resumed package name changed?
17138        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17139                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17140            if (mCurResumedPackage != null) {
17141                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17142                        mCurResumedPackage, mCurResumedUid);
17143            }
17144            mCurResumedPackage = pkg;
17145            mCurResumedUid = uid;
17146            if (mCurResumedPackage != null) {
17147                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17148                        mCurResumedPackage, mCurResumedUid);
17149            }
17150        }
17151        return act;
17152    }
17153
17154    final boolean updateOomAdjLocked(ProcessRecord app) {
17155        final ActivityRecord TOP_ACT = resumedAppLocked();
17156        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17157        final boolean wasCached = app.cached;
17158
17159        mAdjSeq++;
17160
17161        // This is the desired cached adjusment we want to tell it to use.
17162        // If our app is currently cached, we know it, and that is it.  Otherwise,
17163        // we don't know it yet, and it needs to now be cached we will then
17164        // need to do a complete oom adj.
17165        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17166                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17167        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17168                SystemClock.uptimeMillis());
17169        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17170            // Changed to/from cached state, so apps after it in the LRU
17171            // list may also be changed.
17172            updateOomAdjLocked();
17173        }
17174        return success;
17175    }
17176
17177    final void updateOomAdjLocked() {
17178        final ActivityRecord TOP_ACT = resumedAppLocked();
17179        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17180        final long now = SystemClock.uptimeMillis();
17181        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17182        final int N = mLruProcesses.size();
17183
17184        if (false) {
17185            RuntimeException e = new RuntimeException();
17186            e.fillInStackTrace();
17187            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17188        }
17189
17190        mAdjSeq++;
17191        mNewNumServiceProcs = 0;
17192        mNewNumAServiceProcs = 0;
17193
17194        final int emptyProcessLimit;
17195        final int cachedProcessLimit;
17196        if (mProcessLimit <= 0) {
17197            emptyProcessLimit = cachedProcessLimit = 0;
17198        } else if (mProcessLimit == 1) {
17199            emptyProcessLimit = 1;
17200            cachedProcessLimit = 0;
17201        } else {
17202            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17203            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17204        }
17205
17206        // Let's determine how many processes we have running vs.
17207        // how many slots we have for background processes; we may want
17208        // to put multiple processes in a slot of there are enough of
17209        // them.
17210        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17211                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17212        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17213        if (numEmptyProcs > cachedProcessLimit) {
17214            // If there are more empty processes than our limit on cached
17215            // processes, then use the cached process limit for the factor.
17216            // This ensures that the really old empty processes get pushed
17217            // down to the bottom, so if we are running low on memory we will
17218            // have a better chance at keeping around more cached processes
17219            // instead of a gazillion empty processes.
17220            numEmptyProcs = cachedProcessLimit;
17221        }
17222        int emptyFactor = numEmptyProcs/numSlots;
17223        if (emptyFactor < 1) emptyFactor = 1;
17224        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17225        if (cachedFactor < 1) cachedFactor = 1;
17226        int stepCached = 0;
17227        int stepEmpty = 0;
17228        int numCached = 0;
17229        int numEmpty = 0;
17230        int numTrimming = 0;
17231
17232        mNumNonCachedProcs = 0;
17233        mNumCachedHiddenProcs = 0;
17234
17235        // First update the OOM adjustment for each of the
17236        // application processes based on their current state.
17237        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17238        int nextCachedAdj = curCachedAdj+1;
17239        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17240        int nextEmptyAdj = curEmptyAdj+2;
17241        for (int i=N-1; i>=0; i--) {
17242            ProcessRecord app = mLruProcesses.get(i);
17243            if (!app.killedByAm && app.thread != null) {
17244                app.procStateChanged = false;
17245                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17246
17247                // If we haven't yet assigned the final cached adj
17248                // to the process, do that now.
17249                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17250                    switch (app.curProcState) {
17251                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17252                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17253                            // This process is a cached process holding activities...
17254                            // assign it the next cached value for that type, and then
17255                            // step that cached level.
17256                            app.curRawAdj = curCachedAdj;
17257                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17258                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17259                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17260                                    + ")");
17261                            if (curCachedAdj != nextCachedAdj) {
17262                                stepCached++;
17263                                if (stepCached >= cachedFactor) {
17264                                    stepCached = 0;
17265                                    curCachedAdj = nextCachedAdj;
17266                                    nextCachedAdj += 2;
17267                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17268                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17269                                    }
17270                                }
17271                            }
17272                            break;
17273                        default:
17274                            // For everything else, assign next empty cached process
17275                            // level and bump that up.  Note that this means that
17276                            // long-running services that have dropped down to the
17277                            // cached level will be treated as empty (since their process
17278                            // state is still as a service), which is what we want.
17279                            app.curRawAdj = curEmptyAdj;
17280                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17281                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17282                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17283                                    + ")");
17284                            if (curEmptyAdj != nextEmptyAdj) {
17285                                stepEmpty++;
17286                                if (stepEmpty >= emptyFactor) {
17287                                    stepEmpty = 0;
17288                                    curEmptyAdj = nextEmptyAdj;
17289                                    nextEmptyAdj += 2;
17290                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17291                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17292                                    }
17293                                }
17294                            }
17295                            break;
17296                    }
17297                }
17298
17299                applyOomAdjLocked(app, TOP_APP, true, now);
17300
17301                // Count the number of process types.
17302                switch (app.curProcState) {
17303                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17304                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17305                        mNumCachedHiddenProcs++;
17306                        numCached++;
17307                        if (numCached > cachedProcessLimit) {
17308                            app.kill("cached #" + numCached, true);
17309                        }
17310                        break;
17311                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17312                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17313                                && app.lastActivityTime < oldTime) {
17314                            app.kill("empty for "
17315                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17316                                    / 1000) + "s", true);
17317                        } else {
17318                            numEmpty++;
17319                            if (numEmpty > emptyProcessLimit) {
17320                                app.kill("empty #" + numEmpty, true);
17321                            }
17322                        }
17323                        break;
17324                    default:
17325                        mNumNonCachedProcs++;
17326                        break;
17327                }
17328
17329                if (app.isolated && app.services.size() <= 0) {
17330                    // If this is an isolated process, and there are no
17331                    // services running in it, then the process is no longer
17332                    // needed.  We agressively kill these because we can by
17333                    // definition not re-use the same process again, and it is
17334                    // good to avoid having whatever code was running in them
17335                    // left sitting around after no longer needed.
17336                    app.kill("isolated not needed", true);
17337                }
17338
17339                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17340                        && !app.killedByAm) {
17341                    numTrimming++;
17342                }
17343            }
17344        }
17345
17346        mNumServiceProcs = mNewNumServiceProcs;
17347
17348        // Now determine the memory trimming level of background processes.
17349        // Unfortunately we need to start at the back of the list to do this
17350        // properly.  We only do this if the number of background apps we
17351        // are managing to keep around is less than half the maximum we desire;
17352        // if we are keeping a good number around, we'll let them use whatever
17353        // memory they want.
17354        final int numCachedAndEmpty = numCached + numEmpty;
17355        int memFactor;
17356        if (numCached <= ProcessList.TRIM_CACHED_APPS
17357                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17358            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17359                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17360            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17361                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17362            } else {
17363                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17364            }
17365        } else {
17366            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17367        }
17368        // We always allow the memory level to go up (better).  We only allow it to go
17369        // down if we are in a state where that is allowed, *and* the total number of processes
17370        // has gone down since last time.
17371        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17372                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17373                + " last=" + mLastNumProcesses);
17374        if (memFactor > mLastMemoryLevel) {
17375            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17376                memFactor = mLastMemoryLevel;
17377                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17378            }
17379        }
17380        mLastMemoryLevel = memFactor;
17381        mLastNumProcesses = mLruProcesses.size();
17382        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17383        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17384        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17385            if (mLowRamStartTime == 0) {
17386                mLowRamStartTime = now;
17387            }
17388            int step = 0;
17389            int fgTrimLevel;
17390            switch (memFactor) {
17391                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17392                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17393                    break;
17394                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17395                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17396                    break;
17397                default:
17398                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17399                    break;
17400            }
17401            int factor = numTrimming/3;
17402            int minFactor = 2;
17403            if (mHomeProcess != null) minFactor++;
17404            if (mPreviousProcess != null) minFactor++;
17405            if (factor < minFactor) factor = minFactor;
17406            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17407            for (int i=N-1; i>=0; i--) {
17408                ProcessRecord app = mLruProcesses.get(i);
17409                if (allChanged || app.procStateChanged) {
17410                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17411                    app.procStateChanged = false;
17412                }
17413                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17414                        && !app.killedByAm) {
17415                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17416                        try {
17417                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17418                                    "Trimming memory of " + app.processName
17419                                    + " to " + curLevel);
17420                            app.thread.scheduleTrimMemory(curLevel);
17421                        } catch (RemoteException e) {
17422                        }
17423                        if (false) {
17424                            // For now we won't do this; our memory trimming seems
17425                            // to be good enough at this point that destroying
17426                            // activities causes more harm than good.
17427                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17428                                    && app != mHomeProcess && app != mPreviousProcess) {
17429                                // Need to do this on its own message because the stack may not
17430                                // be in a consistent state at this point.
17431                                // For these apps we will also finish their activities
17432                                // to help them free memory.
17433                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17434                            }
17435                        }
17436                    }
17437                    app.trimMemoryLevel = curLevel;
17438                    step++;
17439                    if (step >= factor) {
17440                        step = 0;
17441                        switch (curLevel) {
17442                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17443                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17444                                break;
17445                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17446                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17447                                break;
17448                        }
17449                    }
17450                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17451                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17452                            && app.thread != null) {
17453                        try {
17454                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17455                                    "Trimming memory of heavy-weight " + app.processName
17456                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17457                            app.thread.scheduleTrimMemory(
17458                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17459                        } catch (RemoteException e) {
17460                        }
17461                    }
17462                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17463                } else {
17464                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17465                            || app.systemNoUi) && app.pendingUiClean) {
17466                        // If this application is now in the background and it
17467                        // had done UI, then give it the special trim level to
17468                        // have it free UI resources.
17469                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17470                        if (app.trimMemoryLevel < level && app.thread != null) {
17471                            try {
17472                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17473                                        "Trimming memory of bg-ui " + app.processName
17474                                        + " to " + level);
17475                                app.thread.scheduleTrimMemory(level);
17476                            } catch (RemoteException e) {
17477                            }
17478                        }
17479                        app.pendingUiClean = false;
17480                    }
17481                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17482                        try {
17483                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17484                                    "Trimming memory of fg " + app.processName
17485                                    + " to " + fgTrimLevel);
17486                            app.thread.scheduleTrimMemory(fgTrimLevel);
17487                        } catch (RemoteException e) {
17488                        }
17489                    }
17490                    app.trimMemoryLevel = fgTrimLevel;
17491                }
17492            }
17493        } else {
17494            if (mLowRamStartTime != 0) {
17495                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17496                mLowRamStartTime = 0;
17497            }
17498            for (int i=N-1; i>=0; i--) {
17499                ProcessRecord app = mLruProcesses.get(i);
17500                if (allChanged || app.procStateChanged) {
17501                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17502                    app.procStateChanged = false;
17503                }
17504                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17505                        || app.systemNoUi) && app.pendingUiClean) {
17506                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17507                            && app.thread != null) {
17508                        try {
17509                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17510                                    "Trimming memory of ui hidden " + app.processName
17511                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17512                            app.thread.scheduleTrimMemory(
17513                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17514                        } catch (RemoteException e) {
17515                        }
17516                    }
17517                    app.pendingUiClean = false;
17518                }
17519                app.trimMemoryLevel = 0;
17520            }
17521        }
17522
17523        if (mAlwaysFinishActivities) {
17524            // Need to do this on its own message because the stack may not
17525            // be in a consistent state at this point.
17526            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17527        }
17528
17529        if (allChanged) {
17530            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17531        }
17532
17533        if (mProcessStats.shouldWriteNowLocked(now)) {
17534            mHandler.post(new Runnable() {
17535                @Override public void run() {
17536                    synchronized (ActivityManagerService.this) {
17537                        mProcessStats.writeStateAsyncLocked();
17538                    }
17539                }
17540            });
17541        }
17542
17543        if (DEBUG_OOM_ADJ) {
17544            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17545        }
17546    }
17547
17548    final void trimApplications() {
17549        synchronized (this) {
17550            int i;
17551
17552            // First remove any unused application processes whose package
17553            // has been removed.
17554            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
17555                final ProcessRecord app = mRemovedProcesses.get(i);
17556                if (app.activities.size() == 0
17557                        && app.curReceiver == null && app.services.size() == 0) {
17558                    Slog.i(
17559                        TAG, "Exiting empty application process "
17560                        + app.processName + " ("
17561                        + (app.thread != null ? app.thread.asBinder() : null)
17562                        + ")\n");
17563                    if (app.pid > 0 && app.pid != MY_PID) {
17564                        app.kill("empty", false);
17565                    } else {
17566                        try {
17567                            app.thread.scheduleExit();
17568                        } catch (Exception e) {
17569                            // Ignore exceptions.
17570                        }
17571                    }
17572                    cleanUpApplicationRecordLocked(app, false, true, -1);
17573                    mRemovedProcesses.remove(i);
17574
17575                    if (app.persistent) {
17576                        addAppLocked(app.info, false, null /* ABI override */);
17577                    }
17578                }
17579            }
17580
17581            // Now update the oom adj for all processes.
17582            updateOomAdjLocked();
17583        }
17584    }
17585
17586    /** This method sends the specified signal to each of the persistent apps */
17587    public void signalPersistentProcesses(int sig) throws RemoteException {
17588        if (sig != Process.SIGNAL_USR1) {
17589            throw new SecurityException("Only SIGNAL_USR1 is allowed");
17590        }
17591
17592        synchronized (this) {
17593            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
17594                    != PackageManager.PERMISSION_GRANTED) {
17595                throw new SecurityException("Requires permission "
17596                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
17597            }
17598
17599            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17600                ProcessRecord r = mLruProcesses.get(i);
17601                if (r.thread != null && r.persistent) {
17602                    Process.sendSignal(r.pid, sig);
17603                }
17604            }
17605        }
17606    }
17607
17608    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
17609        if (proc == null || proc == mProfileProc) {
17610            proc = mProfileProc;
17611            path = mProfileFile;
17612            profileType = mProfileType;
17613            clearProfilerLocked();
17614        }
17615        if (proc == null) {
17616            return;
17617        }
17618        try {
17619            proc.thread.profilerControl(false, path, null, profileType);
17620        } catch (RemoteException e) {
17621            throw new IllegalStateException("Process disappeared");
17622        }
17623    }
17624
17625    private void clearProfilerLocked() {
17626        if (mProfileFd != null) {
17627            try {
17628                mProfileFd.close();
17629            } catch (IOException e) {
17630            }
17631        }
17632        mProfileApp = null;
17633        mProfileProc = null;
17634        mProfileFile = null;
17635        mProfileType = 0;
17636        mAutoStopProfiler = false;
17637    }
17638
17639    public boolean profileControl(String process, int userId, boolean start,
17640            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
17641
17642        try {
17643            synchronized (this) {
17644                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17645                // its own permission.
17646                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17647                        != PackageManager.PERMISSION_GRANTED) {
17648                    throw new SecurityException("Requires permission "
17649                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17650                }
17651
17652                if (start && fd == null) {
17653                    throw new IllegalArgumentException("null fd");
17654                }
17655
17656                ProcessRecord proc = null;
17657                if (process != null) {
17658                    proc = findProcessLocked(process, userId, "profileControl");
17659                }
17660
17661                if (start && (proc == null || proc.thread == null)) {
17662                    throw new IllegalArgumentException("Unknown process: " + process);
17663                }
17664
17665                if (start) {
17666                    stopProfilerLocked(null, null, 0);
17667                    setProfileApp(proc.info, proc.processName, path, fd, false);
17668                    mProfileProc = proc;
17669                    mProfileType = profileType;
17670                    try {
17671                        fd = fd.dup();
17672                    } catch (IOException e) {
17673                        fd = null;
17674                    }
17675                    proc.thread.profilerControl(start, path, fd, profileType);
17676                    fd = null;
17677                    mProfileFd = null;
17678                } else {
17679                    stopProfilerLocked(proc, path, profileType);
17680                    if (fd != null) {
17681                        try {
17682                            fd.close();
17683                        } catch (IOException e) {
17684                        }
17685                    }
17686                }
17687
17688                return true;
17689            }
17690        } catch (RemoteException e) {
17691            throw new IllegalStateException("Process disappeared");
17692        } finally {
17693            if (fd != null) {
17694                try {
17695                    fd.close();
17696                } catch (IOException e) {
17697                }
17698            }
17699        }
17700    }
17701
17702    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
17703        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17704                userId, true, ALLOW_FULL_ONLY, callName, null);
17705        ProcessRecord proc = null;
17706        try {
17707            int pid = Integer.parseInt(process);
17708            synchronized (mPidsSelfLocked) {
17709                proc = mPidsSelfLocked.get(pid);
17710            }
17711        } catch (NumberFormatException e) {
17712        }
17713
17714        if (proc == null) {
17715            ArrayMap<String, SparseArray<ProcessRecord>> all
17716                    = mProcessNames.getMap();
17717            SparseArray<ProcessRecord> procs = all.get(process);
17718            if (procs != null && procs.size() > 0) {
17719                proc = procs.valueAt(0);
17720                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
17721                    for (int i=1; i<procs.size(); i++) {
17722                        ProcessRecord thisProc = procs.valueAt(i);
17723                        if (thisProc.userId == userId) {
17724                            proc = thisProc;
17725                            break;
17726                        }
17727                    }
17728                }
17729            }
17730        }
17731
17732        return proc;
17733    }
17734
17735    public boolean dumpHeap(String process, int userId, boolean managed,
17736            String path, ParcelFileDescriptor fd) throws RemoteException {
17737
17738        try {
17739            synchronized (this) {
17740                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17741                // its own permission (same as profileControl).
17742                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17743                        != PackageManager.PERMISSION_GRANTED) {
17744                    throw new SecurityException("Requires permission "
17745                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17746                }
17747
17748                if (fd == null) {
17749                    throw new IllegalArgumentException("null fd");
17750                }
17751
17752                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
17753                if (proc == null || proc.thread == null) {
17754                    throw new IllegalArgumentException("Unknown process: " + process);
17755                }
17756
17757                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17758                if (!isDebuggable) {
17759                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
17760                        throw new SecurityException("Process not debuggable: " + proc);
17761                    }
17762                }
17763
17764                proc.thread.dumpHeap(managed, path, fd);
17765                fd = null;
17766                return true;
17767            }
17768        } catch (RemoteException e) {
17769            throw new IllegalStateException("Process disappeared");
17770        } finally {
17771            if (fd != null) {
17772                try {
17773                    fd.close();
17774                } catch (IOException e) {
17775                }
17776            }
17777        }
17778    }
17779
17780    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
17781    public void monitor() {
17782        synchronized (this) { }
17783    }
17784
17785    void onCoreSettingsChange(Bundle settings) {
17786        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17787            ProcessRecord processRecord = mLruProcesses.get(i);
17788            try {
17789                if (processRecord.thread != null) {
17790                    processRecord.thread.setCoreSettings(settings);
17791                }
17792            } catch (RemoteException re) {
17793                /* ignore */
17794            }
17795        }
17796    }
17797
17798    // Multi-user methods
17799
17800    /**
17801     * Start user, if its not already running, but don't bring it to foreground.
17802     */
17803    @Override
17804    public boolean startUserInBackground(final int userId) {
17805        return startUser(userId, /* foreground */ false);
17806    }
17807
17808    /**
17809     * Start user, if its not already running, and bring it to foreground.
17810     */
17811    boolean startUserInForeground(final int userId, Dialog dlg) {
17812        boolean result = startUser(userId, /* foreground */ true);
17813        dlg.dismiss();
17814        return result;
17815    }
17816
17817    /**
17818     * Refreshes the list of users related to the current user when either a
17819     * user switch happens or when a new related user is started in the
17820     * background.
17821     */
17822    private void updateCurrentProfileIdsLocked() {
17823        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17824                mCurrentUserId, false /* enabledOnly */);
17825        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17826        for (int i = 0; i < currentProfileIds.length; i++) {
17827            currentProfileIds[i] = profiles.get(i).id;
17828        }
17829        mCurrentProfileIds = currentProfileIds;
17830
17831        synchronized (mUserProfileGroupIdsSelfLocked) {
17832            mUserProfileGroupIdsSelfLocked.clear();
17833            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17834            for (int i = 0; i < users.size(); i++) {
17835                UserInfo user = users.get(i);
17836                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17837                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17838                }
17839            }
17840        }
17841    }
17842
17843    private Set getProfileIdsLocked(int userId) {
17844        Set userIds = new HashSet<Integer>();
17845        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17846                userId, false /* enabledOnly */);
17847        for (UserInfo user : profiles) {
17848            userIds.add(Integer.valueOf(user.id));
17849        }
17850        return userIds;
17851    }
17852
17853    @Override
17854    public boolean switchUser(final int userId) {
17855        String userName;
17856        synchronized (this) {
17857            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17858            if (userInfo == null) {
17859                Slog.w(TAG, "No user info for user #" + userId);
17860                return false;
17861            }
17862            if (userInfo.isManagedProfile()) {
17863                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
17864                return false;
17865            }
17866            userName = userInfo.name;
17867        }
17868        mHandler.removeMessages(START_USER_SWITCH_MSG);
17869        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
17870        return true;
17871    }
17872
17873    private void showUserSwitchDialog(int userId, String userName) {
17874        // The dialog will show and then initiate the user switch by calling startUserInForeground
17875        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
17876                true /* above system */);
17877        d.show();
17878    }
17879
17880    private boolean startUser(final int userId, final boolean foreground) {
17881        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17882                != PackageManager.PERMISSION_GRANTED) {
17883            String msg = "Permission Denial: switchUser() from pid="
17884                    + Binder.getCallingPid()
17885                    + ", uid=" + Binder.getCallingUid()
17886                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17887            Slog.w(TAG, msg);
17888            throw new SecurityException(msg);
17889        }
17890
17891        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
17892
17893        final long ident = Binder.clearCallingIdentity();
17894        try {
17895            synchronized (this) {
17896                final int oldUserId = mCurrentUserId;
17897                if (oldUserId == userId) {
17898                    return true;
17899                }
17900
17901                mStackSupervisor.setLockTaskModeLocked(null, false);
17902
17903                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17904                if (userInfo == null) {
17905                    Slog.w(TAG, "No user info for user #" + userId);
17906                    return false;
17907                }
17908                if (foreground && userInfo.isManagedProfile()) {
17909                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
17910                    return false;
17911                }
17912
17913                if (foreground) {
17914                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
17915                            R.anim.screen_user_enter);
17916                }
17917
17918                boolean needStart = false;
17919
17920                // If the user we are switching to is not currently started, then
17921                // we need to start it now.
17922                if (mStartedUsers.get(userId) == null) {
17923                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
17924                    updateStartedUserArrayLocked();
17925                    needStart = true;
17926                }
17927
17928                final Integer userIdInt = Integer.valueOf(userId);
17929                mUserLru.remove(userIdInt);
17930                mUserLru.add(userIdInt);
17931
17932                if (foreground) {
17933                    mCurrentUserId = userId;
17934                    updateCurrentProfileIdsLocked();
17935                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
17936                    // Once the internal notion of the active user has switched, we lock the device
17937                    // with the option to show the user switcher on the keyguard.
17938                    mWindowManager.lockNow(null);
17939                } else {
17940                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
17941                    updateCurrentProfileIdsLocked();
17942                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
17943                    mUserLru.remove(currentUserIdInt);
17944                    mUserLru.add(currentUserIdInt);
17945                }
17946
17947                final UserStartedState uss = mStartedUsers.get(userId);
17948
17949                // Make sure user is in the started state.  If it is currently
17950                // stopping, we need to knock that off.
17951                if (uss.mState == UserStartedState.STATE_STOPPING) {
17952                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
17953                    // so we can just fairly silently bring the user back from
17954                    // the almost-dead.
17955                    uss.mState = UserStartedState.STATE_RUNNING;
17956                    updateStartedUserArrayLocked();
17957                    needStart = true;
17958                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
17959                    // This means ACTION_SHUTDOWN has been sent, so we will
17960                    // need to treat this as a new boot of the user.
17961                    uss.mState = UserStartedState.STATE_BOOTING;
17962                    updateStartedUserArrayLocked();
17963                    needStart = true;
17964                }
17965
17966                if (uss.mState == UserStartedState.STATE_BOOTING) {
17967                    // Booting up a new user, need to tell system services about it.
17968                    // Note that this is on the same handler as scheduling of broadcasts,
17969                    // which is important because it needs to go first.
17970                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
17971                }
17972
17973                if (foreground) {
17974                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
17975                            oldUserId));
17976                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
17977                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17978                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
17979                            oldUserId, userId, uss));
17980                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
17981                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
17982                }
17983
17984                if (needStart) {
17985                    // Send USER_STARTED broadcast
17986                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
17987                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17988                            | Intent.FLAG_RECEIVER_FOREGROUND);
17989                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17990                    broadcastIntentLocked(null, null, intent,
17991                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17992                            false, false, MY_PID, Process.SYSTEM_UID, userId);
17993                }
17994
17995                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
17996                    if (userId != UserHandle.USER_OWNER) {
17997                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
17998                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17999                        broadcastIntentLocked(null, null, intent, null,
18000                                new IIntentReceiver.Stub() {
18001                                    public void performReceive(Intent intent, int resultCode,
18002                                            String data, Bundle extras, boolean ordered,
18003                                            boolean sticky, int sendingUser) {
18004                                        onUserInitialized(uss, foreground, oldUserId, userId);
18005                                    }
18006                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18007                                true, false, MY_PID, Process.SYSTEM_UID,
18008                                userId);
18009                        uss.initializing = true;
18010                    } else {
18011                        getUserManagerLocked().makeInitialized(userInfo.id);
18012                    }
18013                }
18014
18015                if (foreground) {
18016                    if (!uss.initializing) {
18017                        moveUserToForeground(uss, oldUserId, userId);
18018                    }
18019                } else {
18020                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18021                }
18022
18023                if (needStart) {
18024                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18025                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18026                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18027                    broadcastIntentLocked(null, null, intent,
18028                            null, new IIntentReceiver.Stub() {
18029                                @Override
18030                                public void performReceive(Intent intent, int resultCode, String data,
18031                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18032                                        throws RemoteException {
18033                                }
18034                            }, 0, null, null,
18035                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18036                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18037                }
18038            }
18039        } finally {
18040            Binder.restoreCallingIdentity(ident);
18041        }
18042
18043        return true;
18044    }
18045
18046    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18047        long ident = Binder.clearCallingIdentity();
18048        try {
18049            Intent intent;
18050            if (oldUserId >= 0) {
18051                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18052                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18053                int count = profiles.size();
18054                for (int i = 0; i < count; i++) {
18055                    int profileUserId = profiles.get(i).id;
18056                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18057                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18058                            | Intent.FLAG_RECEIVER_FOREGROUND);
18059                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18060                    broadcastIntentLocked(null, null, intent,
18061                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18062                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18063                }
18064            }
18065            if (newUserId >= 0) {
18066                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18067                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18068                int count = profiles.size();
18069                for (int i = 0; i < count; i++) {
18070                    int profileUserId = profiles.get(i).id;
18071                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18072                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18073                            | Intent.FLAG_RECEIVER_FOREGROUND);
18074                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18075                    broadcastIntentLocked(null, null, intent,
18076                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18077                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18078                }
18079                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18080                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18081                        | Intent.FLAG_RECEIVER_FOREGROUND);
18082                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18083                broadcastIntentLocked(null, null, intent,
18084                        null, null, 0, null, null,
18085                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18086                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18087            }
18088        } finally {
18089            Binder.restoreCallingIdentity(ident);
18090        }
18091    }
18092
18093    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18094            final int newUserId) {
18095        final int N = mUserSwitchObservers.beginBroadcast();
18096        if (N > 0) {
18097            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18098                int mCount = 0;
18099                @Override
18100                public void sendResult(Bundle data) throws RemoteException {
18101                    synchronized (ActivityManagerService.this) {
18102                        if (mCurUserSwitchCallback == this) {
18103                            mCount++;
18104                            if (mCount == N) {
18105                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18106                            }
18107                        }
18108                    }
18109                }
18110            };
18111            synchronized (this) {
18112                uss.switching = true;
18113                mCurUserSwitchCallback = callback;
18114            }
18115            for (int i=0; i<N; i++) {
18116                try {
18117                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18118                            newUserId, callback);
18119                } catch (RemoteException e) {
18120                }
18121            }
18122        } else {
18123            synchronized (this) {
18124                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18125            }
18126        }
18127        mUserSwitchObservers.finishBroadcast();
18128    }
18129
18130    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18131        synchronized (this) {
18132            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18133            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18134        }
18135    }
18136
18137    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18138        mCurUserSwitchCallback = null;
18139        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18140        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18141                oldUserId, newUserId, uss));
18142    }
18143
18144    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18145        synchronized (this) {
18146            if (foreground) {
18147                moveUserToForeground(uss, oldUserId, newUserId);
18148            }
18149        }
18150
18151        completeSwitchAndInitalize(uss, newUserId, true, false);
18152    }
18153
18154    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18155        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18156        if (homeInFront) {
18157            startHomeActivityLocked(newUserId);
18158        } else {
18159            mStackSupervisor.resumeTopActivitiesLocked();
18160        }
18161        EventLogTags.writeAmSwitchUser(newUserId);
18162        getUserManagerLocked().userForeground(newUserId);
18163        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18164    }
18165
18166    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18167        completeSwitchAndInitalize(uss, newUserId, false, true);
18168    }
18169
18170    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18171            boolean clearInitializing, boolean clearSwitching) {
18172        boolean unfrozen = false;
18173        synchronized (this) {
18174            if (clearInitializing) {
18175                uss.initializing = false;
18176                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18177            }
18178            if (clearSwitching) {
18179                uss.switching = false;
18180            }
18181            if (!uss.switching && !uss.initializing) {
18182                mWindowManager.stopFreezingScreen();
18183                unfrozen = true;
18184            }
18185        }
18186        if (unfrozen) {
18187            final int N = mUserSwitchObservers.beginBroadcast();
18188            for (int i=0; i<N; i++) {
18189                try {
18190                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18191                } catch (RemoteException e) {
18192                }
18193            }
18194            mUserSwitchObservers.finishBroadcast();
18195        }
18196    }
18197
18198    void scheduleStartProfilesLocked() {
18199        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18200            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18201                    DateUtils.SECOND_IN_MILLIS);
18202        }
18203    }
18204
18205    void startProfilesLocked() {
18206        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18207        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18208                mCurrentUserId, false /* enabledOnly */);
18209        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18210        for (UserInfo user : profiles) {
18211            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18212                    && user.id != mCurrentUserId) {
18213                toStart.add(user);
18214            }
18215        }
18216        final int n = toStart.size();
18217        int i = 0;
18218        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18219            startUserInBackground(toStart.get(i).id);
18220        }
18221        if (i < n) {
18222            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18223        }
18224    }
18225
18226    void finishUserBoot(UserStartedState uss) {
18227        synchronized (this) {
18228            if (uss.mState == UserStartedState.STATE_BOOTING
18229                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18230                uss.mState = UserStartedState.STATE_RUNNING;
18231                final int userId = uss.mHandle.getIdentifier();
18232                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18233                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18234                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18235                broadcastIntentLocked(null, null, intent,
18236                        null, null, 0, null, null,
18237                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18238                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18239            }
18240        }
18241    }
18242
18243    void finishUserSwitch(UserStartedState uss) {
18244        synchronized (this) {
18245            finishUserBoot(uss);
18246
18247            startProfilesLocked();
18248
18249            int num = mUserLru.size();
18250            int i = 0;
18251            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18252                Integer oldUserId = mUserLru.get(i);
18253                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18254                if (oldUss == null) {
18255                    // Shouldn't happen, but be sane if it does.
18256                    mUserLru.remove(i);
18257                    num--;
18258                    continue;
18259                }
18260                if (oldUss.mState == UserStartedState.STATE_STOPPING
18261                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18262                    // This user is already stopping, doesn't count.
18263                    num--;
18264                    i++;
18265                    continue;
18266                }
18267                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18268                    // Owner and current can't be stopped, but count as running.
18269                    i++;
18270                    continue;
18271                }
18272                // This is a user to be stopped.
18273                stopUserLocked(oldUserId, null);
18274                num--;
18275                i++;
18276            }
18277        }
18278    }
18279
18280    @Override
18281    public int stopUser(final int userId, final IStopUserCallback callback) {
18282        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18283                != PackageManager.PERMISSION_GRANTED) {
18284            String msg = "Permission Denial: switchUser() from pid="
18285                    + Binder.getCallingPid()
18286                    + ", uid=" + Binder.getCallingUid()
18287                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18288            Slog.w(TAG, msg);
18289            throw new SecurityException(msg);
18290        }
18291        if (userId <= 0) {
18292            throw new IllegalArgumentException("Can't stop primary user " + userId);
18293        }
18294        synchronized (this) {
18295            return stopUserLocked(userId, callback);
18296        }
18297    }
18298
18299    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18300        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18301        if (mCurrentUserId == userId) {
18302            return ActivityManager.USER_OP_IS_CURRENT;
18303        }
18304
18305        final UserStartedState uss = mStartedUsers.get(userId);
18306        if (uss == null) {
18307            // User is not started, nothing to do...  but we do need to
18308            // callback if requested.
18309            if (callback != null) {
18310                mHandler.post(new Runnable() {
18311                    @Override
18312                    public void run() {
18313                        try {
18314                            callback.userStopped(userId);
18315                        } catch (RemoteException e) {
18316                        }
18317                    }
18318                });
18319            }
18320            return ActivityManager.USER_OP_SUCCESS;
18321        }
18322
18323        if (callback != null) {
18324            uss.mStopCallbacks.add(callback);
18325        }
18326
18327        if (uss.mState != UserStartedState.STATE_STOPPING
18328                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18329            uss.mState = UserStartedState.STATE_STOPPING;
18330            updateStartedUserArrayLocked();
18331
18332            long ident = Binder.clearCallingIdentity();
18333            try {
18334                // We are going to broadcast ACTION_USER_STOPPING and then
18335                // once that is done send a final ACTION_SHUTDOWN and then
18336                // stop the user.
18337                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18338                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18339                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18340                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18341                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18342                // This is the result receiver for the final shutdown broadcast.
18343                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18344                    @Override
18345                    public void performReceive(Intent intent, int resultCode, String data,
18346                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18347                        finishUserStop(uss);
18348                    }
18349                };
18350                // This is the result receiver for the initial stopping broadcast.
18351                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18352                    @Override
18353                    public void performReceive(Intent intent, int resultCode, String data,
18354                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18355                        // On to the next.
18356                        synchronized (ActivityManagerService.this) {
18357                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18358                                // Whoops, we are being started back up.  Abort, abort!
18359                                return;
18360                            }
18361                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18362                        }
18363                        mBatteryStatsService.noteEvent(
18364                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18365                                Integer.toString(userId), userId);
18366                        mSystemServiceManager.stopUser(userId);
18367                        broadcastIntentLocked(null, null, shutdownIntent,
18368                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18369                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18370                    }
18371                };
18372                // Kick things off.
18373                broadcastIntentLocked(null, null, stoppingIntent,
18374                        null, stoppingReceiver, 0, null, null,
18375                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18376                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18377            } finally {
18378                Binder.restoreCallingIdentity(ident);
18379            }
18380        }
18381
18382        return ActivityManager.USER_OP_SUCCESS;
18383    }
18384
18385    void finishUserStop(UserStartedState uss) {
18386        final int userId = uss.mHandle.getIdentifier();
18387        boolean stopped;
18388        ArrayList<IStopUserCallback> callbacks;
18389        synchronized (this) {
18390            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18391            if (mStartedUsers.get(userId) != uss) {
18392                stopped = false;
18393            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18394                stopped = false;
18395            } else {
18396                stopped = true;
18397                // User can no longer run.
18398                mStartedUsers.remove(userId);
18399                mUserLru.remove(Integer.valueOf(userId));
18400                updateStartedUserArrayLocked();
18401
18402                // Clean up all state and processes associated with the user.
18403                // Kill all the processes for the user.
18404                forceStopUserLocked(userId, "finish user");
18405            }
18406
18407            // Explicitly remove the old information in mRecentTasks.
18408            removeRecentTasksForUserLocked(userId);
18409        }
18410
18411        for (int i=0; i<callbacks.size(); i++) {
18412            try {
18413                if (stopped) callbacks.get(i).userStopped(userId);
18414                else callbacks.get(i).userStopAborted(userId);
18415            } catch (RemoteException e) {
18416            }
18417        }
18418
18419        if (stopped) {
18420            mSystemServiceManager.cleanupUser(userId);
18421            synchronized (this) {
18422                mStackSupervisor.removeUserLocked(userId);
18423            }
18424        }
18425    }
18426
18427    @Override
18428    public UserInfo getCurrentUser() {
18429        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18430                != PackageManager.PERMISSION_GRANTED) && (
18431                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18432                != PackageManager.PERMISSION_GRANTED)) {
18433            String msg = "Permission Denial: getCurrentUser() from pid="
18434                    + Binder.getCallingPid()
18435                    + ", uid=" + Binder.getCallingUid()
18436                    + " requires " + INTERACT_ACROSS_USERS;
18437            Slog.w(TAG, msg);
18438            throw new SecurityException(msg);
18439        }
18440        synchronized (this) {
18441            return getUserManagerLocked().getUserInfo(mCurrentUserId);
18442        }
18443    }
18444
18445    int getCurrentUserIdLocked() {
18446        return mCurrentUserId;
18447    }
18448
18449    @Override
18450    public boolean isUserRunning(int userId, boolean orStopped) {
18451        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18452                != PackageManager.PERMISSION_GRANTED) {
18453            String msg = "Permission Denial: isUserRunning() from pid="
18454                    + Binder.getCallingPid()
18455                    + ", uid=" + Binder.getCallingUid()
18456                    + " requires " + INTERACT_ACROSS_USERS;
18457            Slog.w(TAG, msg);
18458            throw new SecurityException(msg);
18459        }
18460        synchronized (this) {
18461            return isUserRunningLocked(userId, orStopped);
18462        }
18463    }
18464
18465    boolean isUserRunningLocked(int userId, boolean orStopped) {
18466        UserStartedState state = mStartedUsers.get(userId);
18467        if (state == null) {
18468            return false;
18469        }
18470        if (orStopped) {
18471            return true;
18472        }
18473        return state.mState != UserStartedState.STATE_STOPPING
18474                && state.mState != UserStartedState.STATE_SHUTDOWN;
18475    }
18476
18477    @Override
18478    public int[] getRunningUserIds() {
18479        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18480                != PackageManager.PERMISSION_GRANTED) {
18481            String msg = "Permission Denial: isUserRunning() from pid="
18482                    + Binder.getCallingPid()
18483                    + ", uid=" + Binder.getCallingUid()
18484                    + " requires " + INTERACT_ACROSS_USERS;
18485            Slog.w(TAG, msg);
18486            throw new SecurityException(msg);
18487        }
18488        synchronized (this) {
18489            return mStartedUserArray;
18490        }
18491    }
18492
18493    private void updateStartedUserArrayLocked() {
18494        int num = 0;
18495        for (int i=0; i<mStartedUsers.size();  i++) {
18496            UserStartedState uss = mStartedUsers.valueAt(i);
18497            // This list does not include stopping users.
18498            if (uss.mState != UserStartedState.STATE_STOPPING
18499                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18500                num++;
18501            }
18502        }
18503        mStartedUserArray = new int[num];
18504        num = 0;
18505        for (int i=0; i<mStartedUsers.size();  i++) {
18506            UserStartedState uss = mStartedUsers.valueAt(i);
18507            if (uss.mState != UserStartedState.STATE_STOPPING
18508                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18509                mStartedUserArray[num] = mStartedUsers.keyAt(i);
18510                num++;
18511            }
18512        }
18513    }
18514
18515    @Override
18516    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18517        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18518                != PackageManager.PERMISSION_GRANTED) {
18519            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
18520                    + Binder.getCallingPid()
18521                    + ", uid=" + Binder.getCallingUid()
18522                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18523            Slog.w(TAG, msg);
18524            throw new SecurityException(msg);
18525        }
18526
18527        mUserSwitchObservers.register(observer);
18528    }
18529
18530    @Override
18531    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
18532        mUserSwitchObservers.unregister(observer);
18533    }
18534
18535    private boolean userExists(int userId) {
18536        if (userId == 0) {
18537            return true;
18538        }
18539        UserManagerService ums = getUserManagerLocked();
18540        return ums != null ? (ums.getUserInfo(userId) != null) : false;
18541    }
18542
18543    int[] getUsersLocked() {
18544        UserManagerService ums = getUserManagerLocked();
18545        return ums != null ? ums.getUserIds() : new int[] { 0 };
18546    }
18547
18548    UserManagerService getUserManagerLocked() {
18549        if (mUserManager == null) {
18550            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
18551            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
18552        }
18553        return mUserManager;
18554    }
18555
18556    private int applyUserId(int uid, int userId) {
18557        return UserHandle.getUid(userId, uid);
18558    }
18559
18560    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
18561        if (info == null) return null;
18562        ApplicationInfo newInfo = new ApplicationInfo(info);
18563        newInfo.uid = applyUserId(info.uid, userId);
18564        newInfo.dataDir = USER_DATA_DIR + userId + "/"
18565                + info.packageName;
18566        return newInfo;
18567    }
18568
18569    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
18570        if (aInfo == null
18571                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
18572            return aInfo;
18573        }
18574
18575        ActivityInfo info = new ActivityInfo(aInfo);
18576        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
18577        return info;
18578    }
18579
18580    private final class LocalService extends ActivityManagerInternal {
18581        @Override
18582        public void goingToSleep() {
18583            ActivityManagerService.this.goingToSleep();
18584        }
18585
18586        @Override
18587        public void wakingUp() {
18588            ActivityManagerService.this.wakingUp();
18589        }
18590
18591        @Override
18592        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
18593                String processName, String abiOverride, int uid, Runnable crashHandler) {
18594            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
18595                    processName, abiOverride, uid, crashHandler);
18596        }
18597    }
18598
18599    /**
18600     * An implementation of IAppTask, that allows an app to manage its own tasks via
18601     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
18602     * only the process that calls getAppTasks() can call the AppTask methods.
18603     */
18604    class AppTaskImpl extends IAppTask.Stub {
18605        private int mTaskId;
18606        private int mCallingUid;
18607
18608        public AppTaskImpl(int taskId, int callingUid) {
18609            mTaskId = taskId;
18610            mCallingUid = callingUid;
18611        }
18612
18613        private void checkCaller() {
18614            if (mCallingUid != Binder.getCallingUid()) {
18615                throw new SecurityException("Caller " + mCallingUid
18616                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
18617            }
18618        }
18619
18620        @Override
18621        public void finishAndRemoveTask() {
18622            checkCaller();
18623
18624            synchronized (ActivityManagerService.this) {
18625                long origId = Binder.clearCallingIdentity();
18626                try {
18627                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18628                    if (tr == null) {
18629                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18630                    }
18631                    // Only kill the process if we are not a new document
18632                    int flags = tr.getBaseIntent().getFlags();
18633                    boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
18634                            Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
18635                    removeTaskByIdLocked(mTaskId,
18636                            !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
18637                } finally {
18638                    Binder.restoreCallingIdentity(origId);
18639                }
18640            }
18641        }
18642
18643        @Override
18644        public ActivityManager.RecentTaskInfo getTaskInfo() {
18645            checkCaller();
18646
18647            synchronized (ActivityManagerService.this) {
18648                long origId = Binder.clearCallingIdentity();
18649                try {
18650                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18651                    if (tr == null) {
18652                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18653                    }
18654                    return createRecentTaskInfoFromTaskRecord(tr);
18655                } finally {
18656                    Binder.restoreCallingIdentity(origId);
18657                }
18658            }
18659        }
18660
18661        @Override
18662        public void moveToFront() {
18663            checkCaller();
18664
18665            final TaskRecord tr;
18666            synchronized (ActivityManagerService.this) {
18667                tr = recentTaskForIdLocked(mTaskId);
18668                if (tr == null) {
18669                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18670                }
18671                if (tr.getRootActivity() != null) {
18672                    long origId = Binder.clearCallingIdentity();
18673                    try {
18674                        moveTaskToFrontLocked(tr.taskId, 0, null);
18675                        return;
18676                    } finally {
18677                        Binder.restoreCallingIdentity(origId);
18678                    }
18679                }
18680            }
18681
18682            startActivityFromRecentsInner(tr.taskId, null);
18683        }
18684
18685        @Override
18686        public int startActivity(IBinder whoThread, String callingPackage,
18687                Intent intent, String resolvedType, Bundle options) {
18688            checkCaller();
18689
18690            int callingUser = UserHandle.getCallingUserId();
18691            TaskRecord tr;
18692            IApplicationThread appThread;
18693            synchronized (ActivityManagerService.this) {
18694                tr = recentTaskForIdLocked(mTaskId);
18695                if (tr == null) {
18696                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18697                }
18698                appThread = ApplicationThreadNative.asInterface(whoThread);
18699                if (appThread == null) {
18700                    throw new IllegalArgumentException("Bad app thread " + appThread);
18701                }
18702            }
18703            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
18704                    resolvedType, null, null, null, null, 0, 0, null, null,
18705                    null, null, options, callingUser, null, tr);
18706        }
18707
18708        @Override
18709        public void setExcludeFromRecents(boolean exclude) {
18710            checkCaller();
18711
18712            synchronized (ActivityManagerService.this) {
18713                long origId = Binder.clearCallingIdentity();
18714                try {
18715                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18716                    if (tr == null) {
18717                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18718                    }
18719                    Intent intent = tr.getBaseIntent();
18720                    if (exclude) {
18721                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18722                    } else {
18723                        intent.setFlags(intent.getFlags()
18724                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18725                    }
18726                } finally {
18727                    Binder.restoreCallingIdentity(origId);
18728                }
18729            }
18730        }
18731    }
18732}
18733