ActivityManagerService.java revision 652973fca83c48d8b4622493f10e656b8d86dd17
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.ProfilerInfo;
41import android.app.admin.DevicePolicyManager;
42import android.app.usage.UsageEvents;
43import android.app.usage.UsageStatsManagerInternal;
44import android.appwidget.AppWidgetManager;
45import android.content.res.Resources;
46import android.graphics.Bitmap;
47import android.graphics.Point;
48import android.graphics.Rect;
49import android.os.BatteryStats;
50import android.os.PersistableBundle;
51import android.service.voice.IVoiceInteractionSession;
52import android.util.ArrayMap;
53import android.util.ArraySet;
54import android.util.SparseIntArray;
55
56import com.android.internal.R;
57import com.android.internal.annotations.GuardedBy;
58import com.android.internal.app.IAppOpsService;
59import com.android.internal.app.IVoiceInteractor;
60import com.android.internal.app.ProcessMap;
61import com.android.internal.app.ProcessStats;
62import com.android.internal.content.PackageMonitor;
63import com.android.internal.os.BackgroundThread;
64import com.android.internal.os.BatteryStatsImpl;
65import com.android.internal.os.ProcessCpuTracker;
66import com.android.internal.os.TransferPipe;
67import com.android.internal.os.Zygote;
68import com.android.internal.util.FastPrintWriter;
69import com.android.internal.util.FastXmlSerializer;
70import com.android.internal.util.MemInfoReader;
71import com.android.internal.util.Preconditions;
72import com.android.server.AppOpsService;
73import com.android.server.AttributeCache;
74import com.android.server.IntentResolver;
75import com.android.server.LocalServices;
76import com.android.server.ServiceThread;
77import com.android.server.SystemService;
78import com.android.server.SystemServiceManager;
79import com.android.server.Watchdog;
80import com.android.server.am.ActivityStack.ActivityState;
81import com.android.server.firewall.IntentFirewall;
82import com.android.server.pm.UserManagerService;
83import com.android.server.wm.AppTransition;
84import com.android.server.wm.WindowManagerService;
85import com.google.android.collect.Lists;
86import com.google.android.collect.Maps;
87
88import libcore.io.IoUtils;
89
90import org.xmlpull.v1.XmlPullParser;
91import org.xmlpull.v1.XmlPullParserException;
92import org.xmlpull.v1.XmlSerializer;
93
94import android.app.Activity;
95import android.app.ActivityManager;
96import android.app.ActivityManager.RunningTaskInfo;
97import android.app.ActivityManager.StackInfo;
98import android.app.ActivityManagerInternal;
99import android.app.ActivityManagerNative;
100import android.app.ActivityOptions;
101import android.app.ActivityThread;
102import android.app.AlertDialog;
103import android.app.AppGlobals;
104import android.app.ApplicationErrorReport;
105import android.app.Dialog;
106import android.app.IActivityController;
107import android.app.IApplicationThread;
108import android.app.IInstrumentationWatcher;
109import android.app.INotificationManager;
110import android.app.IProcessObserver;
111import android.app.IServiceConnection;
112import android.app.IStopUserCallback;
113import android.app.IUiAutomationConnection;
114import android.app.IUserSwitchObserver;
115import android.app.Instrumentation;
116import android.app.Notification;
117import android.app.NotificationManager;
118import android.app.PendingIntent;
119import android.app.backup.IBackupManager;
120import android.content.ActivityNotFoundException;
121import android.content.BroadcastReceiver;
122import android.content.ClipData;
123import android.content.ComponentCallbacks2;
124import android.content.ComponentName;
125import android.content.ContentProvider;
126import android.content.ContentResolver;
127import android.content.Context;
128import android.content.DialogInterface;
129import android.content.IContentProvider;
130import android.content.IIntentReceiver;
131import android.content.IIntentSender;
132import android.content.Intent;
133import android.content.IntentFilter;
134import android.content.IntentSender;
135import android.content.pm.ActivityInfo;
136import android.content.pm.ApplicationInfo;
137import android.content.pm.ConfigurationInfo;
138import android.content.pm.IPackageDataObserver;
139import android.content.pm.IPackageManager;
140import android.content.pm.InstrumentationInfo;
141import android.content.pm.PackageInfo;
142import android.content.pm.PackageManager;
143import android.content.pm.ParceledListSlice;
144import android.content.pm.UserInfo;
145import android.content.pm.PackageManager.NameNotFoundException;
146import android.content.pm.PathPermission;
147import android.content.pm.ProviderInfo;
148import android.content.pm.ResolveInfo;
149import android.content.pm.ServiceInfo;
150import android.content.res.CompatibilityInfo;
151import android.content.res.Configuration;
152import android.net.Proxy;
153import android.net.ProxyInfo;
154import android.net.Uri;
155import android.os.Binder;
156import android.os.Build;
157import android.os.Bundle;
158import android.os.Debug;
159import android.os.DropBoxManager;
160import android.os.Environment;
161import android.os.FactoryTest;
162import android.os.FileObserver;
163import android.os.FileUtils;
164import android.os.Handler;
165import android.os.IBinder;
166import android.os.IPermissionController;
167import android.os.IRemoteCallback;
168import android.os.IUserManager;
169import android.os.Looper;
170import android.os.Message;
171import android.os.Parcel;
172import android.os.ParcelFileDescriptor;
173import android.os.Process;
174import android.os.RemoteCallbackList;
175import android.os.RemoteException;
176import android.os.SELinux;
177import android.os.ServiceManager;
178import android.os.StrictMode;
179import android.os.SystemClock;
180import android.os.SystemProperties;
181import android.os.UpdateLock;
182import android.os.UserHandle;
183import android.provider.Settings;
184import android.text.format.DateUtils;
185import android.text.format.Time;
186import android.util.AtomicFile;
187import android.util.EventLog;
188import android.util.Log;
189import android.util.Pair;
190import android.util.PrintWriterPrinter;
191import android.util.Slog;
192import android.util.SparseArray;
193import android.util.TimeUtils;
194import android.util.Xml;
195import android.view.Gravity;
196import android.view.LayoutInflater;
197import android.view.View;
198import android.view.WindowManager;
199import dalvik.system.VMRuntime;
200
201import java.io.BufferedInputStream;
202import java.io.BufferedOutputStream;
203import java.io.DataInputStream;
204import java.io.DataOutputStream;
205import java.io.File;
206import java.io.FileDescriptor;
207import java.io.FileInputStream;
208import java.io.FileNotFoundException;
209import java.io.FileOutputStream;
210import java.io.IOException;
211import java.io.InputStreamReader;
212import java.io.PrintWriter;
213import java.io.StringWriter;
214import java.lang.ref.WeakReference;
215import java.util.ArrayList;
216import java.util.Arrays;
217import java.util.Collections;
218import java.util.Comparator;
219import java.util.HashMap;
220import java.util.HashSet;
221import java.util.Iterator;
222import java.util.List;
223import java.util.Locale;
224import java.util.Map;
225import java.util.Set;
226import java.util.concurrent.atomic.AtomicBoolean;
227import java.util.concurrent.atomic.AtomicLong;
228
229public final class ActivityManagerService extends ActivityManagerNative
230        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
231
232    private static final String USER_DATA_DIR = "/data/user/";
233    // File that stores last updated system version and called preboot receivers
234    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
235
236    static final String TAG = "ActivityManager";
237    static final String TAG_MU = "ActivityManagerServiceMU";
238    static final boolean DEBUG = false;
239    static final boolean localLOGV = DEBUG;
240    static final boolean DEBUG_BACKUP = localLOGV || false;
241    static final boolean DEBUG_BROADCAST = localLOGV || false;
242    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
243    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
244    static final boolean DEBUG_CLEANUP = localLOGV || false;
245    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
246    static final boolean DEBUG_FOCUS = false;
247    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
248    static final boolean DEBUG_MU = localLOGV || false;
249    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
250    static final boolean DEBUG_LRU = localLOGV || false;
251    static final boolean DEBUG_PAUSE = localLOGV || false;
252    static final boolean DEBUG_POWER = localLOGV || false;
253    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
254    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
255    static final boolean DEBUG_PROCESSES = localLOGV || false;
256    static final boolean DEBUG_PROVIDER = localLOGV || false;
257    static final boolean DEBUG_RESULTS = localLOGV || false;
258    static final boolean DEBUG_SERVICE = localLOGV || false;
259    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
260    static final boolean DEBUG_STACK = localLOGV || false;
261    static final boolean DEBUG_SWITCH = localLOGV || false;
262    static final boolean DEBUG_TASKS = localLOGV || false;
263    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
264    static final boolean DEBUG_TRANSITION = localLOGV || false;
265    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
266    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
267    static final boolean DEBUG_VISBILITY = localLOGV || false;
268    static final boolean DEBUG_PSS = localLOGV || false;
269    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
270    static final boolean DEBUG_RECENTS = localLOGV || false;
271    static final boolean VALIDATE_TOKENS = false;
272    static final boolean SHOW_ACTIVITY_START_TIME = true;
273
274    // Control over CPU and battery monitoring.
275    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
276    static final boolean MONITOR_CPU_USAGE = true;
277    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
278    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
279    static final boolean MONITOR_THREAD_CPU_USAGE = false;
280
281    // The flags that are set for all calls we make to the package manager.
282    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
283
284    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
285
286    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
287
288    // Maximum number recent bitmaps to keep in memory.
289    static final int MAX_RECENT_BITMAPS = 5;
290
291    // Amount of time after a call to stopAppSwitches() during which we will
292    // prevent further untrusted switches from happening.
293    static final long APP_SWITCH_DELAY_TIME = 5*1000;
294
295    // How long we wait for a launched process to attach to the activity manager
296    // before we decide it's never going to come up for real.
297    static final int PROC_START_TIMEOUT = 10*1000;
298
299    // How long we wait for a launched process to attach to the activity manager
300    // before we decide it's never going to come up for real, when the process was
301    // started with a wrapper for instrumentation (such as Valgrind) because it
302    // could take much longer than usual.
303    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
304
305    // How long to wait after going idle before forcing apps to GC.
306    static final int GC_TIMEOUT = 5*1000;
307
308    // The minimum amount of time between successive GC requests for a process.
309    static final int GC_MIN_INTERVAL = 60*1000;
310
311    // The minimum amount of time between successive PSS requests for a process.
312    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
313
314    // The minimum amount of time between successive PSS requests for a process
315    // when the request is due to the memory state being lowered.
316    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
317
318    // The rate at which we check for apps using excessive power -- 15 mins.
319    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
320
321    // The minimum sample duration we will allow before deciding we have
322    // enough data on wake locks to start killing things.
323    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
324
325    // The minimum sample duration we will allow before deciding we have
326    // enough data on CPU usage to start killing things.
327    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
328
329    // How long we allow a receiver to run before giving up on it.
330    static final int BROADCAST_FG_TIMEOUT = 10*1000;
331    static final int BROADCAST_BG_TIMEOUT = 60*1000;
332
333    // How long we wait until we timeout on key dispatching.
334    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
335
336    // How long we wait until we timeout on key dispatching during instrumentation.
337    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
338
339    // Amount of time we wait for observers to handle a user switch before
340    // giving up on them and unfreezing the screen.
341    static final int USER_SWITCH_TIMEOUT = 2*1000;
342
343    // Maximum number of users we allow to be running at a time.
344    static final int MAX_RUNNING_USERS = 3;
345
346    // How long to wait in getAssistContextExtras for the activity and foreground services
347    // to respond with the result.
348    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
349
350    // Maximum number of persisted Uri grants a package is allowed
351    static final int MAX_PERSISTED_URI_GRANTS = 128;
352
353    static final int MY_PID = Process.myPid();
354
355    static final String[] EMPTY_STRING_ARRAY = new String[0];
356
357    // How many bytes to write into the dropbox log before truncating
358    static final int DROPBOX_MAX_SIZE = 256 * 1024;
359
360    // Access modes for handleIncomingUser.
361    static final int ALLOW_NON_FULL = 0;
362    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
363    static final int ALLOW_FULL_ONLY = 2;
364
365    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
366
367    /** All system services */
368    SystemServiceManager mSystemServiceManager;
369
370    /** Run all ActivityStacks through this */
371    ActivityStackSupervisor mStackSupervisor;
372
373    public IntentFirewall mIntentFirewall;
374
375    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
376    // default actuion automatically.  Important for devices without direct input
377    // devices.
378    private boolean mShowDialogs = true;
379
380    BroadcastQueue mFgBroadcastQueue;
381    BroadcastQueue mBgBroadcastQueue;
382    // Convenient for easy iteration over the queues. Foreground is first
383    // so that dispatch of foreground broadcasts gets precedence.
384    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
385
386    BroadcastQueue broadcastQueueForIntent(Intent intent) {
387        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
388        if (DEBUG_BACKGROUND_BROADCAST) {
389            Slog.i(TAG, "Broadcast intent " + intent + " on "
390                    + (isFg ? "foreground" : "background")
391                    + " queue");
392        }
393        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
394    }
395
396    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
397        for (BroadcastQueue queue : mBroadcastQueues) {
398            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
399            if (r != null) {
400                return r;
401            }
402        }
403        return null;
404    }
405
406    /**
407     * Activity we have told the window manager to have key focus.
408     */
409    ActivityRecord mFocusedActivity = null;
410
411    /**
412     * List of intents that were used to start the most recent tasks.
413     */
414    ArrayList<TaskRecord> mRecentTasks;
415    ArraySet<TaskRecord> mTmpRecents = new ArraySet<TaskRecord>();
416
417    /**
418     * For addAppTask: cached of the last activity component that was added.
419     */
420    ComponentName mLastAddedTaskComponent;
421
422    /**
423     * For addAppTask: cached of the last activity uid that was added.
424     */
425    int mLastAddedTaskUid;
426
427    /**
428     * For addAppTask: cached of the last ActivityInfo that was added.
429     */
430    ActivityInfo mLastAddedTaskActivity;
431
432    public class PendingAssistExtras extends Binder implements Runnable {
433        public final ActivityRecord activity;
434        public boolean haveResult = false;
435        public Bundle result = null;
436        public PendingAssistExtras(ActivityRecord _activity) {
437            activity = _activity;
438        }
439        @Override
440        public void run() {
441            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
442            synchronized (this) {
443                haveResult = true;
444                notifyAll();
445            }
446        }
447    }
448
449    final ArrayList<PendingAssistExtras> mPendingAssistExtras
450            = new ArrayList<PendingAssistExtras>();
451
452    /**
453     * Process management.
454     */
455    final ProcessList mProcessList = new ProcessList();
456
457    /**
458     * All of the applications we currently have running organized by name.
459     * The keys are strings of the application package name (as
460     * returned by the package manager), and the keys are ApplicationRecord
461     * objects.
462     */
463    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
464
465    /**
466     * Tracking long-term execution of processes to look for abuse and other
467     * bad app behavior.
468     */
469    final ProcessStatsService mProcessStats;
470
471    /**
472     * The currently running isolated processes.
473     */
474    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
475
476    /**
477     * Counter for assigning isolated process uids, to avoid frequently reusing the
478     * same ones.
479     */
480    int mNextIsolatedProcessUid = 0;
481
482    /**
483     * The currently running heavy-weight process, if any.
484     */
485    ProcessRecord mHeavyWeightProcess = null;
486
487    /**
488     * The last time that various processes have crashed.
489     */
490    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
491
492    /**
493     * Information about a process that is currently marked as bad.
494     */
495    static final class BadProcessInfo {
496        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
497            this.time = time;
498            this.shortMsg = shortMsg;
499            this.longMsg = longMsg;
500            this.stack = stack;
501        }
502
503        final long time;
504        final String shortMsg;
505        final String longMsg;
506        final String stack;
507    }
508
509    /**
510     * Set of applications that we consider to be bad, and will reject
511     * incoming broadcasts from (which the user has no control over).
512     * Processes are added to this set when they have crashed twice within
513     * a minimum amount of time; they are removed from it when they are
514     * later restarted (hopefully due to some user action).  The value is the
515     * time it was added to the list.
516     */
517    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
518
519    /**
520     * All of the processes we currently have running organized by pid.
521     * The keys are the pid running the application.
522     *
523     * <p>NOTE: This object is protected by its own lock, NOT the global
524     * activity manager lock!
525     */
526    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
527
528    /**
529     * All of the processes that have been forced to be foreground.  The key
530     * is the pid of the caller who requested it (we hold a death
531     * link on it).
532     */
533    abstract class ForegroundToken implements IBinder.DeathRecipient {
534        int pid;
535        IBinder token;
536    }
537    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
538
539    /**
540     * List of records for processes that someone had tried to start before the
541     * system was ready.  We don't start them at that point, but ensure they
542     * are started by the time booting is complete.
543     */
544    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
545
546    /**
547     * List of persistent applications that are in the process
548     * of being started.
549     */
550    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
551
552    /**
553     * Processes that are being forcibly torn down.
554     */
555    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
556
557    /**
558     * List of running applications, sorted by recent usage.
559     * The first entry in the list is the least recently used.
560     */
561    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
562
563    /**
564     * Where in mLruProcesses that the processes hosting activities start.
565     */
566    int mLruProcessActivityStart = 0;
567
568    /**
569     * Where in mLruProcesses that the processes hosting services start.
570     * This is after (lower index) than mLruProcessesActivityStart.
571     */
572    int mLruProcessServiceStart = 0;
573
574    /**
575     * List of processes that should gc as soon as things are idle.
576     */
577    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
578
579    /**
580     * Processes we want to collect PSS data from.
581     */
582    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
583
584    /**
585     * Last time we requested PSS data of all processes.
586     */
587    long mLastFullPssTime = SystemClock.uptimeMillis();
588
589    /**
590     * If set, the next time we collect PSS data we should do a full collection
591     * with data from native processes and the kernel.
592     */
593    boolean mFullPssPending = false;
594
595    /**
596     * This is the process holding what we currently consider to be
597     * the "home" activity.
598     */
599    ProcessRecord mHomeProcess;
600
601    /**
602     * This is the process holding the activity the user last visited that
603     * is in a different process from the one they are currently in.
604     */
605    ProcessRecord mPreviousProcess;
606
607    /**
608     * The time at which the previous process was last visible.
609     */
610    long mPreviousProcessVisibleTime;
611
612    /**
613     * Which uses have been started, so are allowed to run code.
614     */
615    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
616
617    /**
618     * LRU list of history of current users.  Most recently current is at the end.
619     */
620    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
621
622    /**
623     * Constant array of the users that are currently started.
624     */
625    int[] mStartedUserArray = new int[] { 0 };
626
627    /**
628     * Registered observers of the user switching mechanics.
629     */
630    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
631            = new RemoteCallbackList<IUserSwitchObserver>();
632
633    /**
634     * Currently active user switch.
635     */
636    Object mCurUserSwitchCallback;
637
638    /**
639     * Packages that the user has asked to have run in screen size
640     * compatibility mode instead of filling the screen.
641     */
642    final CompatModePackages mCompatModePackages;
643
644    /**
645     * Set of IntentSenderRecord objects that are currently active.
646     */
647    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
648            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
649
650    /**
651     * Fingerprints (hashCode()) of stack traces that we've
652     * already logged DropBox entries for.  Guarded by itself.  If
653     * something (rogue user app) forces this over
654     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
655     */
656    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
657    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
658
659    /**
660     * Strict Mode background batched logging state.
661     *
662     * The string buffer is guarded by itself, and its lock is also
663     * used to determine if another batched write is already
664     * in-flight.
665     */
666    private final StringBuilder mStrictModeBuffer = new StringBuilder();
667
668    /**
669     * Keeps track of all IIntentReceivers that have been registered for
670     * broadcasts.  Hash keys are the receiver IBinder, hash value is
671     * a ReceiverList.
672     */
673    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
674            new HashMap<IBinder, ReceiverList>();
675
676    /**
677     * Resolver for broadcast intents to registered receivers.
678     * Holds BroadcastFilter (subclass of IntentFilter).
679     */
680    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
681            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
682        @Override
683        protected boolean allowFilterResult(
684                BroadcastFilter filter, List<BroadcastFilter> dest) {
685            IBinder target = filter.receiverList.receiver.asBinder();
686            for (int i=dest.size()-1; i>=0; i--) {
687                if (dest.get(i).receiverList.receiver.asBinder() == target) {
688                    return false;
689                }
690            }
691            return true;
692        }
693
694        @Override
695        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
696            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
697                    || userId == filter.owningUserId) {
698                return super.newResult(filter, match, userId);
699            }
700            return null;
701        }
702
703        @Override
704        protected BroadcastFilter[] newArray(int size) {
705            return new BroadcastFilter[size];
706        }
707
708        @Override
709        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
710            return packageName.equals(filter.packageName);
711        }
712    };
713
714    /**
715     * State of all active sticky broadcasts per user.  Keys are the action of the
716     * sticky Intent, values are an ArrayList of all broadcasted intents with
717     * that action (which should usually be one).  The SparseArray is keyed
718     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
719     * for stickies that are sent to all users.
720     */
721    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
722            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
723
724    final ActiveServices mServices;
725
726    /**
727     * Backup/restore process management
728     */
729    String mBackupAppName = null;
730    BackupRecord mBackupTarget = null;
731
732    final ProviderMap mProviderMap;
733
734    /**
735     * List of content providers who have clients waiting for them.  The
736     * application is currently being launched and the provider will be
737     * removed from this list once it is published.
738     */
739    final ArrayList<ContentProviderRecord> mLaunchingProviders
740            = new ArrayList<ContentProviderRecord>();
741
742    /**
743     * File storing persisted {@link #mGrantedUriPermissions}.
744     */
745    private final AtomicFile mGrantFile;
746
747    /** XML constants used in {@link #mGrantFile} */
748    private static final String TAG_URI_GRANTS = "uri-grants";
749    private static final String TAG_URI_GRANT = "uri-grant";
750    private static final String ATTR_USER_HANDLE = "userHandle";
751    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
752    private static final String ATTR_TARGET_USER_ID = "targetUserId";
753    private static final String ATTR_SOURCE_PKG = "sourcePkg";
754    private static final String ATTR_TARGET_PKG = "targetPkg";
755    private static final String ATTR_URI = "uri";
756    private static final String ATTR_MODE_FLAGS = "modeFlags";
757    private static final String ATTR_CREATED_TIME = "createdTime";
758    private static final String ATTR_PREFIX = "prefix";
759
760    /**
761     * Global set of specific {@link Uri} permissions that have been granted.
762     * This optimized lookup structure maps from {@link UriPermission#targetUid}
763     * to {@link UriPermission#uri} to {@link UriPermission}.
764     */
765    @GuardedBy("this")
766    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
767            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
768
769    public static class GrantUri {
770        public final int sourceUserId;
771        public final Uri uri;
772        public boolean prefix;
773
774        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
775            this.sourceUserId = sourceUserId;
776            this.uri = uri;
777            this.prefix = prefix;
778        }
779
780        @Override
781        public int hashCode() {
782            return toString().hashCode();
783        }
784
785        @Override
786        public boolean equals(Object o) {
787            if (o instanceof GrantUri) {
788                GrantUri other = (GrantUri) o;
789                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
790                        && prefix == other.prefix;
791            }
792            return false;
793        }
794
795        @Override
796        public String toString() {
797            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
798            if (prefix) result += " [prefix]";
799            return result;
800        }
801
802        public String toSafeString() {
803            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
804            if (prefix) result += " [prefix]";
805            return result;
806        }
807
808        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
809            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
810                    ContentProvider.getUriWithoutUserId(uri), false);
811        }
812    }
813
814    CoreSettingsObserver mCoreSettingsObserver;
815
816    /**
817     * Thread-local storage used to carry caller permissions over through
818     * indirect content-provider access.
819     */
820    private class Identity {
821        public int pid;
822        public int uid;
823
824        Identity(int _pid, int _uid) {
825            pid = _pid;
826            uid = _uid;
827        }
828    }
829
830    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
831
832    /**
833     * All information we have collected about the runtime performance of
834     * any user id that can impact battery performance.
835     */
836    final BatteryStatsService mBatteryStatsService;
837
838    /**
839     * Information about component usage
840     */
841    UsageStatsManagerInternal mUsageStatsService;
842
843    /**
844     * Information about and control over application operations
845     */
846    final AppOpsService mAppOpsService;
847
848    /**
849     * Save recent tasks information across reboots.
850     */
851    final TaskPersister mTaskPersister;
852
853    /**
854     * Current configuration information.  HistoryRecord objects are given
855     * a reference to this object to indicate which configuration they are
856     * currently running in, so this object must be kept immutable.
857     */
858    Configuration mConfiguration = new Configuration();
859
860    /**
861     * Current sequencing integer of the configuration, for skipping old
862     * configurations.
863     */
864    int mConfigurationSeq = 0;
865
866    /**
867     * Hardware-reported OpenGLES version.
868     */
869    final int GL_ES_VERSION;
870
871    /**
872     * List of initialization arguments to pass to all processes when binding applications to them.
873     * For example, references to the commonly used services.
874     */
875    HashMap<String, IBinder> mAppBindArgs;
876
877    /**
878     * Temporary to avoid allocations.  Protected by main lock.
879     */
880    final StringBuilder mStringBuilder = new StringBuilder(256);
881
882    /**
883     * Used to control how we initialize the service.
884     */
885    ComponentName mTopComponent;
886    String mTopAction = Intent.ACTION_MAIN;
887    String mTopData;
888    boolean mProcessesReady = false;
889    boolean mSystemReady = false;
890    boolean mBooting = false;
891    boolean mWaitingUpdate = false;
892    boolean mDidUpdate = false;
893    boolean mOnBattery = false;
894    boolean mLaunchWarningShown = false;
895
896    Context mContext;
897
898    int mFactoryTest;
899
900    boolean mCheckedForSetup;
901
902    /**
903     * The time at which we will allow normal application switches again,
904     * after a call to {@link #stopAppSwitches()}.
905     */
906    long mAppSwitchesAllowedTime;
907
908    /**
909     * This is set to true after the first switch after mAppSwitchesAllowedTime
910     * is set; any switches after that will clear the time.
911     */
912    boolean mDidAppSwitch;
913
914    /**
915     * Last time (in realtime) at which we checked for power usage.
916     */
917    long mLastPowerCheckRealtime;
918
919    /**
920     * Last time (in uptime) at which we checked for power usage.
921     */
922    long mLastPowerCheckUptime;
923
924    /**
925     * Set while we are wanting to sleep, to prevent any
926     * activities from being started/resumed.
927     */
928    private boolean mSleeping = false;
929
930    /**
931     * Set while we are running a voice interaction.  This overrides
932     * sleeping while it is active.
933     */
934    private boolean mRunningVoice = false;
935
936    /**
937     * State of external calls telling us if the device is asleep.
938     */
939    private boolean mWentToSleep = false;
940
941    /**
942     * State of external call telling us if the lock screen is shown.
943     */
944    private boolean mLockScreenShown = false;
945
946    /**
947     * Set if we are shutting down the system, similar to sleeping.
948     */
949    boolean mShuttingDown = false;
950
951    /**
952     * Current sequence id for oom_adj computation traversal.
953     */
954    int mAdjSeq = 0;
955
956    /**
957     * Current sequence id for process LRU updating.
958     */
959    int mLruSeq = 0;
960
961    /**
962     * Keep track of the non-cached/empty process we last found, to help
963     * determine how to distribute cached/empty processes next time.
964     */
965    int mNumNonCachedProcs = 0;
966
967    /**
968     * Keep track of the number of cached hidden procs, to balance oom adj
969     * distribution between those and empty procs.
970     */
971    int mNumCachedHiddenProcs = 0;
972
973    /**
974     * Keep track of the number of service processes we last found, to
975     * determine on the next iteration which should be B services.
976     */
977    int mNumServiceProcs = 0;
978    int mNewNumAServiceProcs = 0;
979    int mNewNumServiceProcs = 0;
980
981    /**
982     * Allow the current computed overall memory level of the system to go down?
983     * This is set to false when we are killing processes for reasons other than
984     * memory management, so that the now smaller process list will not be taken as
985     * an indication that memory is tighter.
986     */
987    boolean mAllowLowerMemLevel = false;
988
989    /**
990     * The last computed memory level, for holding when we are in a state that
991     * processes are going away for other reasons.
992     */
993    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
994
995    /**
996     * The last total number of process we have, to determine if changes actually look
997     * like a shrinking number of process due to lower RAM.
998     */
999    int mLastNumProcesses;
1000
1001    /**
1002     * The uptime of the last time we performed idle maintenance.
1003     */
1004    long mLastIdleTime = SystemClock.uptimeMillis();
1005
1006    /**
1007     * Total time spent with RAM that has been added in the past since the last idle time.
1008     */
1009    long mLowRamTimeSinceLastIdle = 0;
1010
1011    /**
1012     * If RAM is currently low, when that horrible situation started.
1013     */
1014    long mLowRamStartTime = 0;
1015
1016    /**
1017     * For reporting to battery stats the current top application.
1018     */
1019    private String mCurResumedPackage = null;
1020    private int mCurResumedUid = -1;
1021
1022    /**
1023     * For reporting to battery stats the apps currently running foreground
1024     * service.  The ProcessMap is package/uid tuples; each of these contain
1025     * an array of the currently foreground processes.
1026     */
1027    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1028            = new ProcessMap<ArrayList<ProcessRecord>>();
1029
1030    /**
1031     * This is set if we had to do a delayed dexopt of an app before launching
1032     * it, to increase the ANR timeouts in that case.
1033     */
1034    boolean mDidDexOpt;
1035
1036    /**
1037     * Set if the systemServer made a call to enterSafeMode.
1038     */
1039    boolean mSafeMode;
1040
1041    String mDebugApp = null;
1042    boolean mWaitForDebugger = false;
1043    boolean mDebugTransient = false;
1044    String mOrigDebugApp = null;
1045    boolean mOrigWaitForDebugger = false;
1046    boolean mAlwaysFinishActivities = false;
1047    IActivityController mController = null;
1048    String mProfileApp = null;
1049    ProcessRecord mProfileProc = null;
1050    String mProfileFile;
1051    ParcelFileDescriptor mProfileFd;
1052    int mSamplingInterval = 0;
1053    boolean mAutoStopProfiler = false;
1054    int mProfileType = 0;
1055    String mOpenGlTraceApp = null;
1056
1057    static class ProcessChangeItem {
1058        static final int CHANGE_ACTIVITIES = 1<<0;
1059        static final int CHANGE_PROCESS_STATE = 1<<1;
1060        int changes;
1061        int uid;
1062        int pid;
1063        int processState;
1064        boolean foregroundActivities;
1065    }
1066
1067    final RemoteCallbackList<IProcessObserver> mProcessObservers
1068            = new RemoteCallbackList<IProcessObserver>();
1069    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1070
1071    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1072            = new ArrayList<ProcessChangeItem>();
1073    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1074            = new ArrayList<ProcessChangeItem>();
1075
1076    /**
1077     * Runtime CPU use collection thread.  This object's lock is used to
1078     * perform synchronization with the thread (notifying it to run).
1079     */
1080    final Thread mProcessCpuThread;
1081
1082    /**
1083     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1084     * Must acquire this object's lock when accessing it.
1085     * NOTE: this lock will be held while doing long operations (trawling
1086     * through all processes in /proc), so it should never be acquired by
1087     * any critical paths such as when holding the main activity manager lock.
1088     */
1089    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1090            MONITOR_THREAD_CPU_USAGE);
1091    final AtomicLong mLastCpuTime = new AtomicLong(0);
1092    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1093
1094    long mLastWriteTime = 0;
1095
1096    /**
1097     * Used to retain an update lock when the foreground activity is in
1098     * immersive mode.
1099     */
1100    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1101
1102    /**
1103     * Set to true after the system has finished booting.
1104     */
1105    boolean mBooted = false;
1106
1107    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1108    int mProcessLimitOverride = -1;
1109
1110    WindowManagerService mWindowManager;
1111
1112    final ActivityThread mSystemThread;
1113
1114    // Holds the current foreground user's id
1115    int mCurrentUserId = 0;
1116    // Holds the target user's id during a user switch
1117    int mTargetUserId = UserHandle.USER_NULL;
1118    // If there are multiple profiles for the current user, their ids are here
1119    // Currently only the primary user can have managed profiles
1120    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1121
1122    /**
1123     * Mapping from each known user ID to the profile group ID it is associated with.
1124     */
1125    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1126
1127    private UserManagerService mUserManager;
1128
1129    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1130        final ProcessRecord mApp;
1131        final int mPid;
1132        final IApplicationThread mAppThread;
1133
1134        AppDeathRecipient(ProcessRecord app, int pid,
1135                IApplicationThread thread) {
1136            if (localLOGV) Slog.v(
1137                TAG, "New death recipient " + this
1138                + " for thread " + thread.asBinder());
1139            mApp = app;
1140            mPid = pid;
1141            mAppThread = thread;
1142        }
1143
1144        @Override
1145        public void binderDied() {
1146            if (localLOGV) Slog.v(
1147                TAG, "Death received in " + this
1148                + " for thread " + mAppThread.asBinder());
1149            synchronized(ActivityManagerService.this) {
1150                appDiedLocked(mApp, mPid, mAppThread);
1151            }
1152        }
1153    }
1154
1155    static final int SHOW_ERROR_MSG = 1;
1156    static final int SHOW_NOT_RESPONDING_MSG = 2;
1157    static final int SHOW_FACTORY_ERROR_MSG = 3;
1158    static final int UPDATE_CONFIGURATION_MSG = 4;
1159    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1160    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1161    static final int SERVICE_TIMEOUT_MSG = 12;
1162    static final int UPDATE_TIME_ZONE = 13;
1163    static final int SHOW_UID_ERROR_MSG = 14;
1164    static final int IM_FEELING_LUCKY_MSG = 15;
1165    static final int PROC_START_TIMEOUT_MSG = 20;
1166    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1167    static final int KILL_APPLICATION_MSG = 22;
1168    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1169    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1170    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1171    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1172    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1173    static final int CLEAR_DNS_CACHE_MSG = 28;
1174    static final int UPDATE_HTTP_PROXY_MSG = 29;
1175    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1176    static final int DISPATCH_PROCESSES_CHANGED = 31;
1177    static final int DISPATCH_PROCESS_DIED = 32;
1178    static final int REPORT_MEM_USAGE_MSG = 33;
1179    static final int REPORT_USER_SWITCH_MSG = 34;
1180    static final int CONTINUE_USER_SWITCH_MSG = 35;
1181    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1182    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1183    static final int PERSIST_URI_GRANTS_MSG = 38;
1184    static final int REQUEST_ALL_PSS_MSG = 39;
1185    static final int START_PROFILES_MSG = 40;
1186    static final int UPDATE_TIME = 41;
1187    static final int SYSTEM_USER_START_MSG = 42;
1188    static final int SYSTEM_USER_CURRENT_MSG = 43;
1189    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1190    static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45;
1191    static final int START_USER_SWITCH_MSG = 46;
1192
1193    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1194    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1195    static final int FIRST_COMPAT_MODE_MSG = 300;
1196    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1197
1198    AlertDialog mUidAlert;
1199    CompatModeDialog mCompatModeDialog;
1200    long mLastMemUsageReportTime = 0;
1201
1202    private LockToAppRequestDialog mLockToAppRequest;
1203
1204    /**
1205     * Flag whether the current user is a "monkey", i.e. whether
1206     * the UI is driven by a UI automation tool.
1207     */
1208    private boolean mUserIsMonkey;
1209
1210    /** Flag whether the device has a Recents UI */
1211    boolean mHasRecents;
1212
1213    /** The dimensions of the thumbnails in the Recents UI. */
1214    int mThumbnailWidth;
1215    int mThumbnailHeight;
1216
1217    final ServiceThread mHandlerThread;
1218    final MainHandler mHandler;
1219
1220    final class MainHandler extends Handler {
1221        public MainHandler(Looper looper) {
1222            super(looper, null, true);
1223        }
1224
1225        @Override
1226        public void handleMessage(Message msg) {
1227            switch (msg.what) {
1228            case SHOW_ERROR_MSG: {
1229                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1230                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1231                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1232                synchronized (ActivityManagerService.this) {
1233                    ProcessRecord proc = (ProcessRecord)data.get("app");
1234                    AppErrorResult res = (AppErrorResult) data.get("result");
1235                    if (proc != null && proc.crashDialog != null) {
1236                        Slog.e(TAG, "App already has crash dialog: " + proc);
1237                        if (res != null) {
1238                            res.set(0);
1239                        }
1240                        return;
1241                    }
1242                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1243                            >= Process.FIRST_APPLICATION_UID
1244                            && proc.pid != MY_PID);
1245                    for (int userId : mCurrentProfileIds) {
1246                        isBackground &= (proc.userId != userId);
1247                    }
1248                    if (isBackground && !showBackground) {
1249                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1250                        if (res != null) {
1251                            res.set(0);
1252                        }
1253                        return;
1254                    }
1255                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1256                        Dialog d = new AppErrorDialog(mContext,
1257                                ActivityManagerService.this, res, proc);
1258                        d.show();
1259                        proc.crashDialog = d;
1260                    } else {
1261                        // The device is asleep, so just pretend that the user
1262                        // saw a crash dialog and hit "force quit".
1263                        if (res != null) {
1264                            res.set(0);
1265                        }
1266                    }
1267                }
1268
1269                ensureBootCompleted();
1270            } break;
1271            case SHOW_NOT_RESPONDING_MSG: {
1272                synchronized (ActivityManagerService.this) {
1273                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1274                    ProcessRecord proc = (ProcessRecord)data.get("app");
1275                    if (proc != null && proc.anrDialog != null) {
1276                        Slog.e(TAG, "App already has anr dialog: " + proc);
1277                        return;
1278                    }
1279
1280                    Intent intent = new Intent("android.intent.action.ANR");
1281                    if (!mProcessesReady) {
1282                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1283                                | Intent.FLAG_RECEIVER_FOREGROUND);
1284                    }
1285                    broadcastIntentLocked(null, null, intent,
1286                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1287                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1288
1289                    if (mShowDialogs) {
1290                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1291                                mContext, proc, (ActivityRecord)data.get("activity"),
1292                                msg.arg1 != 0);
1293                        d.show();
1294                        proc.anrDialog = d;
1295                    } else {
1296                        // Just kill the app if there is no dialog to be shown.
1297                        killAppAtUsersRequest(proc, null);
1298                    }
1299                }
1300
1301                ensureBootCompleted();
1302            } break;
1303            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1304                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1305                synchronized (ActivityManagerService.this) {
1306                    ProcessRecord proc = (ProcessRecord) data.get("app");
1307                    if (proc == null) {
1308                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1309                        break;
1310                    }
1311                    if (proc.crashDialog != null) {
1312                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1313                        return;
1314                    }
1315                    AppErrorResult res = (AppErrorResult) data.get("result");
1316                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1317                        Dialog d = new StrictModeViolationDialog(mContext,
1318                                ActivityManagerService.this, res, proc);
1319                        d.show();
1320                        proc.crashDialog = d;
1321                    } else {
1322                        // The device is asleep, so just pretend that the user
1323                        // saw a crash dialog and hit "force quit".
1324                        res.set(0);
1325                    }
1326                }
1327                ensureBootCompleted();
1328            } break;
1329            case SHOW_FACTORY_ERROR_MSG: {
1330                Dialog d = new FactoryErrorDialog(
1331                    mContext, msg.getData().getCharSequence("msg"));
1332                d.show();
1333                ensureBootCompleted();
1334            } break;
1335            case UPDATE_CONFIGURATION_MSG: {
1336                final ContentResolver resolver = mContext.getContentResolver();
1337                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1338            } break;
1339            case GC_BACKGROUND_PROCESSES_MSG: {
1340                synchronized (ActivityManagerService.this) {
1341                    performAppGcsIfAppropriateLocked();
1342                }
1343            } break;
1344            case WAIT_FOR_DEBUGGER_MSG: {
1345                synchronized (ActivityManagerService.this) {
1346                    ProcessRecord app = (ProcessRecord)msg.obj;
1347                    if (msg.arg1 != 0) {
1348                        if (!app.waitedForDebugger) {
1349                            Dialog d = new AppWaitingForDebuggerDialog(
1350                                    ActivityManagerService.this,
1351                                    mContext, app);
1352                            app.waitDialog = d;
1353                            app.waitedForDebugger = true;
1354                            d.show();
1355                        }
1356                    } else {
1357                        if (app.waitDialog != null) {
1358                            app.waitDialog.dismiss();
1359                            app.waitDialog = null;
1360                        }
1361                    }
1362                }
1363            } break;
1364            case SERVICE_TIMEOUT_MSG: {
1365                if (mDidDexOpt) {
1366                    mDidDexOpt = false;
1367                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1368                    nmsg.obj = msg.obj;
1369                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1370                    return;
1371                }
1372                mServices.serviceTimeout((ProcessRecord)msg.obj);
1373            } break;
1374            case UPDATE_TIME_ZONE: {
1375                synchronized (ActivityManagerService.this) {
1376                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1377                        ProcessRecord r = mLruProcesses.get(i);
1378                        if (r.thread != null) {
1379                            try {
1380                                r.thread.updateTimeZone();
1381                            } catch (RemoteException ex) {
1382                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1383                            }
1384                        }
1385                    }
1386                }
1387            } break;
1388            case CLEAR_DNS_CACHE_MSG: {
1389                synchronized (ActivityManagerService.this) {
1390                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1391                        ProcessRecord r = mLruProcesses.get(i);
1392                        if (r.thread != null) {
1393                            try {
1394                                r.thread.clearDnsCache();
1395                            } catch (RemoteException ex) {
1396                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1397                            }
1398                        }
1399                    }
1400                }
1401            } break;
1402            case UPDATE_HTTP_PROXY_MSG: {
1403                ProxyInfo proxy = (ProxyInfo)msg.obj;
1404                String host = "";
1405                String port = "";
1406                String exclList = "";
1407                Uri pacFileUrl = Uri.EMPTY;
1408                if (proxy != null) {
1409                    host = proxy.getHost();
1410                    port = Integer.toString(proxy.getPort());
1411                    exclList = proxy.getExclusionListAsString();
1412                    pacFileUrl = proxy.getPacFileUrl();
1413                }
1414                synchronized (ActivityManagerService.this) {
1415                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1416                        ProcessRecord r = mLruProcesses.get(i);
1417                        if (r.thread != null) {
1418                            try {
1419                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1420                            } catch (RemoteException ex) {
1421                                Slog.w(TAG, "Failed to update http proxy for: " +
1422                                        r.info.processName);
1423                            }
1424                        }
1425                    }
1426                }
1427            } break;
1428            case SHOW_UID_ERROR_MSG: {
1429                String title = "System UIDs Inconsistent";
1430                String text = "UIDs on the system are inconsistent, you need to wipe your"
1431                        + " data partition or your device will be unstable.";
1432                Log.e(TAG, title + ": " + text);
1433                if (mShowDialogs) {
1434                    // XXX This is a temporary dialog, no need to localize.
1435                    AlertDialog d = new BaseErrorDialog(mContext);
1436                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1437                    d.setCancelable(false);
1438                    d.setTitle(title);
1439                    d.setMessage(text);
1440                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1441                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1442                    mUidAlert = d;
1443                    d.show();
1444                }
1445            } break;
1446            case IM_FEELING_LUCKY_MSG: {
1447                if (mUidAlert != null) {
1448                    mUidAlert.dismiss();
1449                    mUidAlert = null;
1450                }
1451            } break;
1452            case PROC_START_TIMEOUT_MSG: {
1453                if (mDidDexOpt) {
1454                    mDidDexOpt = false;
1455                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1456                    nmsg.obj = msg.obj;
1457                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1458                    return;
1459                }
1460                ProcessRecord app = (ProcessRecord)msg.obj;
1461                synchronized (ActivityManagerService.this) {
1462                    processStartTimedOutLocked(app);
1463                }
1464            } break;
1465            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1466                synchronized (ActivityManagerService.this) {
1467                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1468                }
1469            } break;
1470            case KILL_APPLICATION_MSG: {
1471                synchronized (ActivityManagerService.this) {
1472                    int appid = msg.arg1;
1473                    boolean restart = (msg.arg2 == 1);
1474                    Bundle bundle = (Bundle)msg.obj;
1475                    String pkg = bundle.getString("pkg");
1476                    String reason = bundle.getString("reason");
1477                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1478                            false, UserHandle.USER_ALL, reason);
1479                }
1480            } break;
1481            case FINALIZE_PENDING_INTENT_MSG: {
1482                ((PendingIntentRecord)msg.obj).completeFinalize();
1483            } break;
1484            case POST_HEAVY_NOTIFICATION_MSG: {
1485                INotificationManager inm = NotificationManager.getService();
1486                if (inm == null) {
1487                    return;
1488                }
1489
1490                ActivityRecord root = (ActivityRecord)msg.obj;
1491                ProcessRecord process = root.app;
1492                if (process == null) {
1493                    return;
1494                }
1495
1496                try {
1497                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1498                    String text = mContext.getString(R.string.heavy_weight_notification,
1499                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1500                    Notification notification = new Notification();
1501                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1502                    notification.when = 0;
1503                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1504                    notification.tickerText = text;
1505                    notification.defaults = 0; // please be quiet
1506                    notification.sound = null;
1507                    notification.vibrate = null;
1508                    notification.color = mContext.getResources().getColor(
1509                            com.android.internal.R.color.system_notification_accent_color);
1510                    notification.setLatestEventInfo(context, text,
1511                            mContext.getText(R.string.heavy_weight_notification_detail),
1512                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1513                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1514                                    new UserHandle(root.userId)));
1515
1516                    try {
1517                        int[] outId = new int[1];
1518                        inm.enqueueNotificationWithTag("android", "android", null,
1519                                R.string.heavy_weight_notification,
1520                                notification, outId, root.userId);
1521                    } catch (RuntimeException e) {
1522                        Slog.w(ActivityManagerService.TAG,
1523                                "Error showing notification for heavy-weight app", e);
1524                    } catch (RemoteException e) {
1525                    }
1526                } catch (NameNotFoundException e) {
1527                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1528                }
1529            } break;
1530            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1531                INotificationManager inm = NotificationManager.getService();
1532                if (inm == null) {
1533                    return;
1534                }
1535                try {
1536                    inm.cancelNotificationWithTag("android", null,
1537                            R.string.heavy_weight_notification,  msg.arg1);
1538                } catch (RuntimeException e) {
1539                    Slog.w(ActivityManagerService.TAG,
1540                            "Error canceling notification for service", e);
1541                } catch (RemoteException e) {
1542                }
1543            } break;
1544            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1545                synchronized (ActivityManagerService.this) {
1546                    checkExcessivePowerUsageLocked(true);
1547                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1548                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1549                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1550                }
1551            } break;
1552            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1553                synchronized (ActivityManagerService.this) {
1554                    ActivityRecord ar = (ActivityRecord)msg.obj;
1555                    if (mCompatModeDialog != null) {
1556                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1557                                ar.info.applicationInfo.packageName)) {
1558                            return;
1559                        }
1560                        mCompatModeDialog.dismiss();
1561                        mCompatModeDialog = null;
1562                    }
1563                    if (ar != null && false) {
1564                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1565                                ar.packageName)) {
1566                            int mode = mCompatModePackages.computeCompatModeLocked(
1567                                    ar.info.applicationInfo);
1568                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1569                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1570                                mCompatModeDialog = new CompatModeDialog(
1571                                        ActivityManagerService.this, mContext,
1572                                        ar.info.applicationInfo);
1573                                mCompatModeDialog.show();
1574                            }
1575                        }
1576                    }
1577                }
1578                break;
1579            }
1580            case DISPATCH_PROCESSES_CHANGED: {
1581                dispatchProcessesChanged();
1582                break;
1583            }
1584            case DISPATCH_PROCESS_DIED: {
1585                final int pid = msg.arg1;
1586                final int uid = msg.arg2;
1587                dispatchProcessDied(pid, uid);
1588                break;
1589            }
1590            case REPORT_MEM_USAGE_MSG: {
1591                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1592                Thread thread = new Thread() {
1593                    @Override public void run() {
1594                        final SparseArray<ProcessMemInfo> infoMap
1595                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1596                        for (int i=0, N=memInfos.size(); i<N; i++) {
1597                            ProcessMemInfo mi = memInfos.get(i);
1598                            infoMap.put(mi.pid, mi);
1599                        }
1600                        updateCpuStatsNow();
1601                        synchronized (mProcessCpuTracker) {
1602                            final int N = mProcessCpuTracker.countStats();
1603                            for (int i=0; i<N; i++) {
1604                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1605                                if (st.vsize > 0) {
1606                                    long pss = Debug.getPss(st.pid, null);
1607                                    if (pss > 0) {
1608                                        if (infoMap.indexOfKey(st.pid) < 0) {
1609                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1610                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1611                                            mi.pss = pss;
1612                                            memInfos.add(mi);
1613                                        }
1614                                    }
1615                                }
1616                            }
1617                        }
1618
1619                        long totalPss = 0;
1620                        for (int i=0, N=memInfos.size(); i<N; i++) {
1621                            ProcessMemInfo mi = memInfos.get(i);
1622                            if (mi.pss == 0) {
1623                                mi.pss = Debug.getPss(mi.pid, null);
1624                            }
1625                            totalPss += mi.pss;
1626                        }
1627                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1628                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1629                                if (lhs.oomAdj != rhs.oomAdj) {
1630                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1631                                }
1632                                if (lhs.pss != rhs.pss) {
1633                                    return lhs.pss < rhs.pss ? 1 : -1;
1634                                }
1635                                return 0;
1636                            }
1637                        });
1638
1639                        StringBuilder tag = new StringBuilder(128);
1640                        StringBuilder stack = new StringBuilder(128);
1641                        tag.append("Low on memory -- ");
1642                        appendMemBucket(tag, totalPss, "total", false);
1643                        appendMemBucket(stack, totalPss, "total", true);
1644
1645                        StringBuilder logBuilder = new StringBuilder(1024);
1646                        logBuilder.append("Low on memory:\n");
1647
1648                        boolean firstLine = true;
1649                        int lastOomAdj = Integer.MIN_VALUE;
1650                        for (int i=0, N=memInfos.size(); i<N; i++) {
1651                            ProcessMemInfo mi = memInfos.get(i);
1652
1653                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1654                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1655                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1656                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1657                                if (lastOomAdj != mi.oomAdj) {
1658                                    lastOomAdj = mi.oomAdj;
1659                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1660                                        tag.append(" / ");
1661                                    }
1662                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1663                                        if (firstLine) {
1664                                            stack.append(":");
1665                                            firstLine = false;
1666                                        }
1667                                        stack.append("\n\t at ");
1668                                    } else {
1669                                        stack.append("$");
1670                                    }
1671                                } else {
1672                                    tag.append(" ");
1673                                    stack.append("$");
1674                                }
1675                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1676                                    appendMemBucket(tag, mi.pss, mi.name, false);
1677                                }
1678                                appendMemBucket(stack, mi.pss, mi.name, true);
1679                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1680                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1681                                    stack.append("(");
1682                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1683                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1684                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1685                                            stack.append(":");
1686                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1687                                        }
1688                                    }
1689                                    stack.append(")");
1690                                }
1691                            }
1692
1693                            logBuilder.append("  ");
1694                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1695                            logBuilder.append(' ');
1696                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1697                            logBuilder.append(' ');
1698                            ProcessList.appendRamKb(logBuilder, mi.pss);
1699                            logBuilder.append(" kB: ");
1700                            logBuilder.append(mi.name);
1701                            logBuilder.append(" (");
1702                            logBuilder.append(mi.pid);
1703                            logBuilder.append(") ");
1704                            logBuilder.append(mi.adjType);
1705                            logBuilder.append('\n');
1706                            if (mi.adjReason != null) {
1707                                logBuilder.append("                      ");
1708                                logBuilder.append(mi.adjReason);
1709                                logBuilder.append('\n');
1710                            }
1711                        }
1712
1713                        logBuilder.append("           ");
1714                        ProcessList.appendRamKb(logBuilder, totalPss);
1715                        logBuilder.append(" kB: TOTAL\n");
1716
1717                        long[] infos = new long[Debug.MEMINFO_COUNT];
1718                        Debug.getMemInfo(infos);
1719                        logBuilder.append("  MemInfo: ");
1720                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1721                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1722                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1723                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1724                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1725                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1726                            logBuilder.append("  ZRAM: ");
1727                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1728                            logBuilder.append(" kB RAM, ");
1729                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1730                            logBuilder.append(" kB swap total, ");
1731                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1732                            logBuilder.append(" kB swap free\n");
1733                        }
1734                        Slog.i(TAG, logBuilder.toString());
1735
1736                        StringBuilder dropBuilder = new StringBuilder(1024);
1737                        /*
1738                        StringWriter oomSw = new StringWriter();
1739                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1740                        StringWriter catSw = new StringWriter();
1741                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1742                        String[] emptyArgs = new String[] { };
1743                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1744                        oomPw.flush();
1745                        String oomString = oomSw.toString();
1746                        */
1747                        dropBuilder.append(stack);
1748                        dropBuilder.append('\n');
1749                        dropBuilder.append('\n');
1750                        dropBuilder.append(logBuilder);
1751                        dropBuilder.append('\n');
1752                        /*
1753                        dropBuilder.append(oomString);
1754                        dropBuilder.append('\n');
1755                        */
1756                        StringWriter catSw = new StringWriter();
1757                        synchronized (ActivityManagerService.this) {
1758                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1759                            String[] emptyArgs = new String[] { };
1760                            catPw.println();
1761                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1762                            catPw.println();
1763                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1764                                    false, false, null);
1765                            catPw.println();
1766                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1767                            catPw.flush();
1768                        }
1769                        dropBuilder.append(catSw.toString());
1770                        addErrorToDropBox("lowmem", null, "system_server", null,
1771                                null, tag.toString(), dropBuilder.toString(), null, null);
1772                        //Slog.i(TAG, "Sent to dropbox:");
1773                        //Slog.i(TAG, dropBuilder.toString());
1774                        synchronized (ActivityManagerService.this) {
1775                            long now = SystemClock.uptimeMillis();
1776                            if (mLastMemUsageReportTime < now) {
1777                                mLastMemUsageReportTime = now;
1778                            }
1779                        }
1780                    }
1781                };
1782                thread.start();
1783                break;
1784            }
1785            case START_USER_SWITCH_MSG: {
1786                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1787                break;
1788            }
1789            case REPORT_USER_SWITCH_MSG: {
1790                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1791                break;
1792            }
1793            case CONTINUE_USER_SWITCH_MSG: {
1794                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1795                break;
1796            }
1797            case USER_SWITCH_TIMEOUT_MSG: {
1798                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1799                break;
1800            }
1801            case IMMERSIVE_MODE_LOCK_MSG: {
1802                final boolean nextState = (msg.arg1 != 0);
1803                if (mUpdateLock.isHeld() != nextState) {
1804                    if (DEBUG_IMMERSIVE) {
1805                        final ActivityRecord r = (ActivityRecord) msg.obj;
1806                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1807                    }
1808                    if (nextState) {
1809                        mUpdateLock.acquire();
1810                    } else {
1811                        mUpdateLock.release();
1812                    }
1813                }
1814                break;
1815            }
1816            case PERSIST_URI_GRANTS_MSG: {
1817                writeGrantedUriPermissions();
1818                break;
1819            }
1820            case REQUEST_ALL_PSS_MSG: {
1821                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1822                break;
1823            }
1824            case START_PROFILES_MSG: {
1825                synchronized (ActivityManagerService.this) {
1826                    startProfilesLocked();
1827                }
1828                break;
1829            }
1830            case UPDATE_TIME: {
1831                synchronized (ActivityManagerService.this) {
1832                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1833                        ProcessRecord r = mLruProcesses.get(i);
1834                        if (r.thread != null) {
1835                            try {
1836                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1837                            } catch (RemoteException ex) {
1838                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1839                            }
1840                        }
1841                    }
1842                }
1843                break;
1844            }
1845            case SYSTEM_USER_START_MSG: {
1846                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1847                        Integer.toString(msg.arg1), msg.arg1);
1848                mSystemServiceManager.startUser(msg.arg1);
1849                break;
1850            }
1851            case SYSTEM_USER_CURRENT_MSG: {
1852                mBatteryStatsService.noteEvent(
1853                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1854                        Integer.toString(msg.arg2), msg.arg2);
1855                mBatteryStatsService.noteEvent(
1856                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1857                        Integer.toString(msg.arg1), msg.arg1);
1858                mSystemServiceManager.switchUser(msg.arg1);
1859                mLockToAppRequest.clearPrompt();
1860                break;
1861            }
1862            case ENTER_ANIMATION_COMPLETE_MSG: {
1863                synchronized (ActivityManagerService.this) {
1864                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1865                    if (r != null && r.app != null && r.app.thread != null) {
1866                        try {
1867                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1868                        } catch (RemoteException e) {
1869                        }
1870                    }
1871                }
1872                break;
1873            }
1874            case ENABLE_SCREEN_AFTER_BOOT_MSG: {
1875                enableScreenAfterBoot();
1876                break;
1877            }
1878            }
1879        }
1880    };
1881
1882    static final int COLLECT_PSS_BG_MSG = 1;
1883
1884    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1885        @Override
1886        public void handleMessage(Message msg) {
1887            switch (msg.what) {
1888            case COLLECT_PSS_BG_MSG: {
1889                long start = SystemClock.uptimeMillis();
1890                MemInfoReader memInfo = null;
1891                synchronized (ActivityManagerService.this) {
1892                    if (mFullPssPending) {
1893                        mFullPssPending = false;
1894                        memInfo = new MemInfoReader();
1895                    }
1896                }
1897                if (memInfo != null) {
1898                    updateCpuStatsNow();
1899                    long nativeTotalPss = 0;
1900                    synchronized (mProcessCpuTracker) {
1901                        final int N = mProcessCpuTracker.countStats();
1902                        for (int j=0; j<N; j++) {
1903                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1904                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1905                                // This is definitely an application process; skip it.
1906                                continue;
1907                            }
1908                            synchronized (mPidsSelfLocked) {
1909                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1910                                    // This is one of our own processes; skip it.
1911                                    continue;
1912                                }
1913                            }
1914                            nativeTotalPss += Debug.getPss(st.pid, null);
1915                        }
1916                    }
1917                    memInfo.readMemInfo();
1918                    synchronized (ActivityManagerService.this) {
1919                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1920                                + (SystemClock.uptimeMillis()-start) + "ms");
1921                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1922                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1923                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1924                                        +memInfo.getSlabSizeKb(),
1925                                nativeTotalPss);
1926                    }
1927                }
1928
1929                int i=0, num=0;
1930                long[] tmp = new long[1];
1931                do {
1932                    ProcessRecord proc;
1933                    int procState;
1934                    int pid;
1935                    synchronized (ActivityManagerService.this) {
1936                        if (i >= mPendingPssProcesses.size()) {
1937                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1938                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1939                            mPendingPssProcesses.clear();
1940                            return;
1941                        }
1942                        proc = mPendingPssProcesses.get(i);
1943                        procState = proc.pssProcState;
1944                        if (proc.thread != null && procState == proc.setProcState) {
1945                            pid = proc.pid;
1946                        } else {
1947                            proc = null;
1948                            pid = 0;
1949                        }
1950                        i++;
1951                    }
1952                    if (proc != null) {
1953                        long pss = Debug.getPss(pid, tmp);
1954                        synchronized (ActivityManagerService.this) {
1955                            if (proc.thread != null && proc.setProcState == procState
1956                                    && proc.pid == pid) {
1957                                num++;
1958                                proc.lastPssTime = SystemClock.uptimeMillis();
1959                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1960                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1961                                        + ": " + pss + " lastPss=" + proc.lastPss
1962                                        + " state=" + ProcessList.makeProcStateString(procState));
1963                                if (proc.initialIdlePss == 0) {
1964                                    proc.initialIdlePss = pss;
1965                                }
1966                                proc.lastPss = pss;
1967                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1968                                    proc.lastCachedPss = pss;
1969                                }
1970                            }
1971                        }
1972                    }
1973                } while (true);
1974            }
1975            }
1976        }
1977    };
1978
1979    /**
1980     * Monitor for package changes and update our internal state.
1981     */
1982    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1983        @Override
1984        public void onPackageRemoved(String packageName, int uid) {
1985            // Remove all tasks with activities in the specified package from the list of recent tasks
1986            synchronized (ActivityManagerService.this) {
1987                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1988                    TaskRecord tr = mRecentTasks.get(i);
1989                    ComponentName cn = tr.intent.getComponent();
1990                    if (cn != null && cn.getPackageName().equals(packageName)) {
1991                        // If the package name matches, remove the task and kill the process
1992                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1993                    }
1994                }
1995            }
1996        }
1997
1998        @Override
1999        public boolean onPackageChanged(String packageName, int uid, String[] components) {
2000            onPackageModified(packageName);
2001            return true;
2002        }
2003
2004        @Override
2005        public void onPackageModified(String packageName) {
2006            final PackageManager pm = mContext.getPackageManager();
2007            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
2008                    new ArrayList<Pair<Intent, Integer>>();
2009            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
2010            // Copy the list of recent tasks so that we don't hold onto the lock on
2011            // ActivityManagerService for long periods while checking if components exist.
2012            synchronized (ActivityManagerService.this) {
2013                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2014                    TaskRecord tr = mRecentTasks.get(i);
2015                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
2016                }
2017            }
2018            // Check the recent tasks and filter out all tasks with components that no longer exist.
2019            Intent tmpI = new Intent();
2020            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
2021                Pair<Intent, Integer> p = recentTaskIntents.get(i);
2022                ComponentName cn = p.first.getComponent();
2023                if (cn != null && cn.getPackageName().equals(packageName)) {
2024                    try {
2025                        // Add the task to the list to remove if the component no longer exists
2026                        tmpI.setComponent(cn);
2027                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
2028                            tasksToRemove.add(p.second);
2029                        }
2030                    } catch (Exception e) {}
2031                }
2032            }
2033            // Prune all the tasks with removed components from the list of recent tasks
2034            synchronized (ActivityManagerService.this) {
2035                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
2036                    // Remove the task but don't kill the process (since other components in that
2037                    // package may still be running and in the background)
2038                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
2039                }
2040            }
2041        }
2042
2043        @Override
2044        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2045            // Force stop the specified packages
2046            if (packages != null) {
2047                for (String pkg : packages) {
2048                    synchronized (ActivityManagerService.this) {
2049                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
2050                                "finished booting")) {
2051                            return true;
2052                        }
2053                    }
2054                }
2055            }
2056            return false;
2057        }
2058    };
2059
2060    public void setSystemProcess() {
2061        try {
2062            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2063            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2064            ServiceManager.addService("meminfo", new MemBinder(this));
2065            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2066            ServiceManager.addService("dbinfo", new DbBinder(this));
2067            if (MONITOR_CPU_USAGE) {
2068                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2069            }
2070            ServiceManager.addService("permission", new PermissionController(this));
2071
2072            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2073                    "android", STOCK_PM_FLAGS);
2074            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2075
2076            synchronized (this) {
2077                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2078                app.persistent = true;
2079                app.pid = MY_PID;
2080                app.maxAdj = ProcessList.SYSTEM_ADJ;
2081                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2082                mProcessNames.put(app.processName, app.uid, app);
2083                synchronized (mPidsSelfLocked) {
2084                    mPidsSelfLocked.put(app.pid, app);
2085                }
2086                updateLruProcessLocked(app, false, null);
2087                updateOomAdjLocked();
2088            }
2089        } catch (PackageManager.NameNotFoundException e) {
2090            throw new RuntimeException(
2091                    "Unable to find android system package", e);
2092        }
2093    }
2094
2095    public void setWindowManager(WindowManagerService wm) {
2096        mWindowManager = wm;
2097        mStackSupervisor.setWindowManager(wm);
2098    }
2099
2100    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2101        mUsageStatsService = usageStatsManager;
2102    }
2103
2104    public void startObservingNativeCrashes() {
2105        final NativeCrashListener ncl = new NativeCrashListener(this);
2106        ncl.start();
2107    }
2108
2109    public IAppOpsService getAppOpsService() {
2110        return mAppOpsService;
2111    }
2112
2113    static class MemBinder extends Binder {
2114        ActivityManagerService mActivityManagerService;
2115        MemBinder(ActivityManagerService activityManagerService) {
2116            mActivityManagerService = activityManagerService;
2117        }
2118
2119        @Override
2120        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2121            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2122                    != PackageManager.PERMISSION_GRANTED) {
2123                pw.println("Permission Denial: can't dump meminfo from from pid="
2124                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2125                        + " without permission " + android.Manifest.permission.DUMP);
2126                return;
2127            }
2128
2129            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2130        }
2131    }
2132
2133    static class GraphicsBinder extends Binder {
2134        ActivityManagerService mActivityManagerService;
2135        GraphicsBinder(ActivityManagerService activityManagerService) {
2136            mActivityManagerService = activityManagerService;
2137        }
2138
2139        @Override
2140        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2141            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2142                    != PackageManager.PERMISSION_GRANTED) {
2143                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2144                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2145                        + " without permission " + android.Manifest.permission.DUMP);
2146                return;
2147            }
2148
2149            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2150        }
2151    }
2152
2153    static class DbBinder extends Binder {
2154        ActivityManagerService mActivityManagerService;
2155        DbBinder(ActivityManagerService activityManagerService) {
2156            mActivityManagerService = activityManagerService;
2157        }
2158
2159        @Override
2160        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2161            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2162                    != PackageManager.PERMISSION_GRANTED) {
2163                pw.println("Permission Denial: can't dump dbinfo from from pid="
2164                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2165                        + " without permission " + android.Manifest.permission.DUMP);
2166                return;
2167            }
2168
2169            mActivityManagerService.dumpDbInfo(fd, pw, args);
2170        }
2171    }
2172
2173    static class CpuBinder extends Binder {
2174        ActivityManagerService mActivityManagerService;
2175        CpuBinder(ActivityManagerService activityManagerService) {
2176            mActivityManagerService = activityManagerService;
2177        }
2178
2179        @Override
2180        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2181            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2182                    != PackageManager.PERMISSION_GRANTED) {
2183                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2184                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2185                        + " without permission " + android.Manifest.permission.DUMP);
2186                return;
2187            }
2188
2189            synchronized (mActivityManagerService.mProcessCpuTracker) {
2190                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2191                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2192                        SystemClock.uptimeMillis()));
2193            }
2194        }
2195    }
2196
2197    public static final class Lifecycle extends SystemService {
2198        private final ActivityManagerService mService;
2199
2200        public Lifecycle(Context context) {
2201            super(context);
2202            mService = new ActivityManagerService(context);
2203        }
2204
2205        @Override
2206        public void onStart() {
2207            mService.start();
2208        }
2209
2210        public ActivityManagerService getService() {
2211            return mService;
2212        }
2213    }
2214
2215    // Note: This method is invoked on the main thread but may need to attach various
2216    // handlers to other threads.  So take care to be explicit about the looper.
2217    public ActivityManagerService(Context systemContext) {
2218        mContext = systemContext;
2219        mFactoryTest = FactoryTest.getMode();
2220        mSystemThread = ActivityThread.currentActivityThread();
2221
2222        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2223
2224        mHandlerThread = new ServiceThread(TAG,
2225                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2226        mHandlerThread.start();
2227        mHandler = new MainHandler(mHandlerThread.getLooper());
2228
2229        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2230                "foreground", BROADCAST_FG_TIMEOUT, false);
2231        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2232                "background", BROADCAST_BG_TIMEOUT, true);
2233        mBroadcastQueues[0] = mFgBroadcastQueue;
2234        mBroadcastQueues[1] = mBgBroadcastQueue;
2235
2236        mServices = new ActiveServices(this);
2237        mProviderMap = new ProviderMap(this);
2238
2239        // TODO: Move creation of battery stats service outside of activity manager service.
2240        File dataDir = Environment.getDataDirectory();
2241        File systemDir = new File(dataDir, "system");
2242        systemDir.mkdirs();
2243        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2244        mBatteryStatsService.getActiveStatistics().readLocked();
2245        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2246        mOnBattery = DEBUG_POWER ? true
2247                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2248        mBatteryStatsService.getActiveStatistics().setCallback(this);
2249
2250        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2251
2252        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2253
2254        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2255
2256        // User 0 is the first and only user that runs at boot.
2257        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2258        mUserLru.add(Integer.valueOf(0));
2259        updateStartedUserArrayLocked();
2260
2261        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2262            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2263
2264        mConfiguration.setToDefaults();
2265        mConfiguration.setLocale(Locale.getDefault());
2266
2267        mConfigurationSeq = mConfiguration.seq = 1;
2268        mProcessCpuTracker.init();
2269
2270        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2271        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2272        mStackSupervisor = new ActivityStackSupervisor(this);
2273        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2274
2275        mProcessCpuThread = new Thread("CpuTracker") {
2276            @Override
2277            public void run() {
2278                while (true) {
2279                    try {
2280                        try {
2281                            synchronized(this) {
2282                                final long now = SystemClock.uptimeMillis();
2283                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2284                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2285                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2286                                //        + ", write delay=" + nextWriteDelay);
2287                                if (nextWriteDelay < nextCpuDelay) {
2288                                    nextCpuDelay = nextWriteDelay;
2289                                }
2290                                if (nextCpuDelay > 0) {
2291                                    mProcessCpuMutexFree.set(true);
2292                                    this.wait(nextCpuDelay);
2293                                }
2294                            }
2295                        } catch (InterruptedException e) {
2296                        }
2297                        updateCpuStatsNow();
2298                    } catch (Exception e) {
2299                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2300                    }
2301                }
2302            }
2303        };
2304
2305        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2306
2307        Watchdog.getInstance().addMonitor(this);
2308        Watchdog.getInstance().addThread(mHandler);
2309    }
2310
2311    public void setSystemServiceManager(SystemServiceManager mgr) {
2312        mSystemServiceManager = mgr;
2313    }
2314
2315    private void start() {
2316        Process.removeAllProcessGroups();
2317        mProcessCpuThread.start();
2318
2319        mBatteryStatsService.publish(mContext);
2320        mAppOpsService.publish(mContext);
2321        Slog.d("AppOps", "AppOpsService published");
2322        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2323    }
2324
2325    public void initPowerManagement() {
2326        mStackSupervisor.initPowerManagement();
2327        mBatteryStatsService.initPowerManagement();
2328    }
2329
2330    @Override
2331    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2332            throws RemoteException {
2333        if (code == SYSPROPS_TRANSACTION) {
2334            // We need to tell all apps about the system property change.
2335            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2336            synchronized(this) {
2337                final int NP = mProcessNames.getMap().size();
2338                for (int ip=0; ip<NP; ip++) {
2339                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2340                    final int NA = apps.size();
2341                    for (int ia=0; ia<NA; ia++) {
2342                        ProcessRecord app = apps.valueAt(ia);
2343                        if (app.thread != null) {
2344                            procs.add(app.thread.asBinder());
2345                        }
2346                    }
2347                }
2348            }
2349
2350            int N = procs.size();
2351            for (int i=0; i<N; i++) {
2352                Parcel data2 = Parcel.obtain();
2353                try {
2354                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2355                } catch (RemoteException e) {
2356                }
2357                data2.recycle();
2358            }
2359        }
2360        try {
2361            return super.onTransact(code, data, reply, flags);
2362        } catch (RuntimeException e) {
2363            // The activity manager only throws security exceptions, so let's
2364            // log all others.
2365            if (!(e instanceof SecurityException)) {
2366                Slog.wtf(TAG, "Activity Manager Crash", e);
2367            }
2368            throw e;
2369        }
2370    }
2371
2372    void updateCpuStats() {
2373        final long now = SystemClock.uptimeMillis();
2374        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2375            return;
2376        }
2377        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2378            synchronized (mProcessCpuThread) {
2379                mProcessCpuThread.notify();
2380            }
2381        }
2382    }
2383
2384    void updateCpuStatsNow() {
2385        synchronized (mProcessCpuTracker) {
2386            mProcessCpuMutexFree.set(false);
2387            final long now = SystemClock.uptimeMillis();
2388            boolean haveNewCpuStats = false;
2389
2390            if (MONITOR_CPU_USAGE &&
2391                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2392                mLastCpuTime.set(now);
2393                haveNewCpuStats = true;
2394                mProcessCpuTracker.update();
2395                //Slog.i(TAG, mProcessCpu.printCurrentState());
2396                //Slog.i(TAG, "Total CPU usage: "
2397                //        + mProcessCpu.getTotalCpuPercent() + "%");
2398
2399                // Slog the cpu usage if the property is set.
2400                if ("true".equals(SystemProperties.get("events.cpu"))) {
2401                    int user = mProcessCpuTracker.getLastUserTime();
2402                    int system = mProcessCpuTracker.getLastSystemTime();
2403                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2404                    int irq = mProcessCpuTracker.getLastIrqTime();
2405                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2406                    int idle = mProcessCpuTracker.getLastIdleTime();
2407
2408                    int total = user + system + iowait + irq + softIrq + idle;
2409                    if (total == 0) total = 1;
2410
2411                    EventLog.writeEvent(EventLogTags.CPU,
2412                            ((user+system+iowait+irq+softIrq) * 100) / total,
2413                            (user * 100) / total,
2414                            (system * 100) / total,
2415                            (iowait * 100) / total,
2416                            (irq * 100) / total,
2417                            (softIrq * 100) / total);
2418                }
2419            }
2420
2421            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2422            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2423            synchronized(bstats) {
2424                synchronized(mPidsSelfLocked) {
2425                    if (haveNewCpuStats) {
2426                        if (mOnBattery) {
2427                            int perc = bstats.startAddingCpuLocked();
2428                            int totalUTime = 0;
2429                            int totalSTime = 0;
2430                            final int N = mProcessCpuTracker.countStats();
2431                            for (int i=0; i<N; i++) {
2432                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2433                                if (!st.working) {
2434                                    continue;
2435                                }
2436                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2437                                int otherUTime = (st.rel_utime*perc)/100;
2438                                int otherSTime = (st.rel_stime*perc)/100;
2439                                totalUTime += otherUTime;
2440                                totalSTime += otherSTime;
2441                                if (pr != null) {
2442                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2443                                    if (ps == null || !ps.isActive()) {
2444                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2445                                                pr.info.uid, pr.processName);
2446                                    }
2447                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2448                                            st.rel_stime-otherSTime);
2449                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2450                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2451                                } else {
2452                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2453                                    if (ps == null || !ps.isActive()) {
2454                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2455                                                bstats.mapUid(st.uid), st.name);
2456                                    }
2457                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2458                                            st.rel_stime-otherSTime);
2459                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2460                                }
2461                            }
2462                            bstats.finishAddingCpuLocked(perc, totalUTime,
2463                                    totalSTime, cpuSpeedTimes);
2464                        }
2465                    }
2466                }
2467
2468                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2469                    mLastWriteTime = now;
2470                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2471                }
2472            }
2473        }
2474    }
2475
2476    @Override
2477    public void batteryNeedsCpuUpdate() {
2478        updateCpuStatsNow();
2479    }
2480
2481    @Override
2482    public void batteryPowerChanged(boolean onBattery) {
2483        // When plugging in, update the CPU stats first before changing
2484        // the plug state.
2485        updateCpuStatsNow();
2486        synchronized (this) {
2487            synchronized(mPidsSelfLocked) {
2488                mOnBattery = DEBUG_POWER ? true : onBattery;
2489            }
2490        }
2491    }
2492
2493    /**
2494     * Initialize the application bind args. These are passed to each
2495     * process when the bindApplication() IPC is sent to the process. They're
2496     * lazily setup to make sure the services are running when they're asked for.
2497     */
2498    private HashMap<String, IBinder> getCommonServicesLocked() {
2499        if (mAppBindArgs == null) {
2500            mAppBindArgs = new HashMap<String, IBinder>();
2501
2502            // Setup the application init args
2503            mAppBindArgs.put("package", ServiceManager.getService("package"));
2504            mAppBindArgs.put("window", ServiceManager.getService("window"));
2505            mAppBindArgs.put(Context.ALARM_SERVICE,
2506                    ServiceManager.getService(Context.ALARM_SERVICE));
2507        }
2508        return mAppBindArgs;
2509    }
2510
2511    final void setFocusedActivityLocked(ActivityRecord r) {
2512        if (mFocusedActivity != r) {
2513            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2514            mFocusedActivity = r;
2515            if (r.task != null && r.task.voiceInteractor != null) {
2516                startRunningVoiceLocked();
2517            } else {
2518                finishRunningVoiceLocked();
2519            }
2520            mStackSupervisor.setFocusedStack(r);
2521            if (r != null) {
2522                mWindowManager.setFocusedApp(r.appToken, true);
2523            }
2524            applyUpdateLockStateLocked(r);
2525        }
2526    }
2527
2528    final void clearFocusedActivity(ActivityRecord r) {
2529        if (mFocusedActivity == r) {
2530            mFocusedActivity = null;
2531        }
2532    }
2533
2534    @Override
2535    public void setFocusedStack(int stackId) {
2536        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2537        synchronized (ActivityManagerService.this) {
2538            ActivityStack stack = mStackSupervisor.getStack(stackId);
2539            if (stack != null) {
2540                ActivityRecord r = stack.topRunningActivityLocked(null);
2541                if (r != null) {
2542                    setFocusedActivityLocked(r);
2543                }
2544            }
2545        }
2546    }
2547
2548    @Override
2549    public void notifyActivityDrawn(IBinder token) {
2550        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2551        synchronized (this) {
2552            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2553            if (r != null) {
2554                r.task.stack.notifyActivityDrawnLocked(r);
2555            }
2556        }
2557    }
2558
2559    final void applyUpdateLockStateLocked(ActivityRecord r) {
2560        // Modifications to the UpdateLock state are done on our handler, outside
2561        // the activity manager's locks.  The new state is determined based on the
2562        // state *now* of the relevant activity record.  The object is passed to
2563        // the handler solely for logging detail, not to be consulted/modified.
2564        final boolean nextState = r != null && r.immersive;
2565        mHandler.sendMessage(
2566                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2567    }
2568
2569    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2570        Message msg = Message.obtain();
2571        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2572        msg.obj = r.task.askedCompatMode ? null : r;
2573        mHandler.sendMessage(msg);
2574    }
2575
2576    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2577            String what, Object obj, ProcessRecord srcApp) {
2578        app.lastActivityTime = now;
2579
2580        if (app.activities.size() > 0) {
2581            // Don't want to touch dependent processes that are hosting activities.
2582            return index;
2583        }
2584
2585        int lrui = mLruProcesses.lastIndexOf(app);
2586        if (lrui < 0) {
2587            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2588                    + what + " " + obj + " from " + srcApp);
2589            return index;
2590        }
2591
2592        if (lrui >= index) {
2593            // Don't want to cause this to move dependent processes *back* in the
2594            // list as if they were less frequently used.
2595            return index;
2596        }
2597
2598        if (lrui >= mLruProcessActivityStart) {
2599            // Don't want to touch dependent processes that are hosting activities.
2600            return index;
2601        }
2602
2603        mLruProcesses.remove(lrui);
2604        if (index > 0) {
2605            index--;
2606        }
2607        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2608                + " in LRU list: " + app);
2609        mLruProcesses.add(index, app);
2610        return index;
2611    }
2612
2613    final void removeLruProcessLocked(ProcessRecord app) {
2614        int lrui = mLruProcesses.lastIndexOf(app);
2615        if (lrui >= 0) {
2616            if (lrui <= mLruProcessActivityStart) {
2617                mLruProcessActivityStart--;
2618            }
2619            if (lrui <= mLruProcessServiceStart) {
2620                mLruProcessServiceStart--;
2621            }
2622            mLruProcesses.remove(lrui);
2623        }
2624    }
2625
2626    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2627            ProcessRecord client) {
2628        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2629                || app.treatLikeActivity;
2630        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2631        if (!activityChange && hasActivity) {
2632            // The process has activities, so we are only allowing activity-based adjustments
2633            // to move it.  It should be kept in the front of the list with other
2634            // processes that have activities, and we don't want those to change their
2635            // order except due to activity operations.
2636            return;
2637        }
2638
2639        mLruSeq++;
2640        final long now = SystemClock.uptimeMillis();
2641        app.lastActivityTime = now;
2642
2643        // First a quick reject: if the app is already at the position we will
2644        // put it, then there is nothing to do.
2645        if (hasActivity) {
2646            final int N = mLruProcesses.size();
2647            if (N > 0 && mLruProcesses.get(N-1) == app) {
2648                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2649                return;
2650            }
2651        } else {
2652            if (mLruProcessServiceStart > 0
2653                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2654                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2655                return;
2656            }
2657        }
2658
2659        int lrui = mLruProcesses.lastIndexOf(app);
2660
2661        if (app.persistent && lrui >= 0) {
2662            // We don't care about the position of persistent processes, as long as
2663            // they are in the list.
2664            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2665            return;
2666        }
2667
2668        /* In progress: compute new position first, so we can avoid doing work
2669           if the process is not actually going to move.  Not yet working.
2670        int addIndex;
2671        int nextIndex;
2672        boolean inActivity = false, inService = false;
2673        if (hasActivity) {
2674            // Process has activities, put it at the very tipsy-top.
2675            addIndex = mLruProcesses.size();
2676            nextIndex = mLruProcessServiceStart;
2677            inActivity = true;
2678        } else if (hasService) {
2679            // Process has services, put it at the top of the service list.
2680            addIndex = mLruProcessActivityStart;
2681            nextIndex = mLruProcessServiceStart;
2682            inActivity = true;
2683            inService = true;
2684        } else  {
2685            // Process not otherwise of interest, it goes to the top of the non-service area.
2686            addIndex = mLruProcessServiceStart;
2687            if (client != null) {
2688                int clientIndex = mLruProcesses.lastIndexOf(client);
2689                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2690                        + app);
2691                if (clientIndex >= 0 && addIndex > clientIndex) {
2692                    addIndex = clientIndex;
2693                }
2694            }
2695            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2696        }
2697
2698        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2699                + mLruProcessActivityStart + "): " + app);
2700        */
2701
2702        if (lrui >= 0) {
2703            if (lrui < mLruProcessActivityStart) {
2704                mLruProcessActivityStart--;
2705            }
2706            if (lrui < mLruProcessServiceStart) {
2707                mLruProcessServiceStart--;
2708            }
2709            /*
2710            if (addIndex > lrui) {
2711                addIndex--;
2712            }
2713            if (nextIndex > lrui) {
2714                nextIndex--;
2715            }
2716            */
2717            mLruProcesses.remove(lrui);
2718        }
2719
2720        /*
2721        mLruProcesses.add(addIndex, app);
2722        if (inActivity) {
2723            mLruProcessActivityStart++;
2724        }
2725        if (inService) {
2726            mLruProcessActivityStart++;
2727        }
2728        */
2729
2730        int nextIndex;
2731        if (hasActivity) {
2732            final int N = mLruProcesses.size();
2733            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2734                // Process doesn't have activities, but has clients with
2735                // activities...  move it up, but one below the top (the top
2736                // should always have a real activity).
2737                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2738                mLruProcesses.add(N-1, app);
2739                // To keep it from spamming the LRU list (by making a bunch of clients),
2740                // we will push down any other entries owned by the app.
2741                final int uid = app.info.uid;
2742                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2743                    ProcessRecord subProc = mLruProcesses.get(i);
2744                    if (subProc.info.uid == uid) {
2745                        // We want to push this one down the list.  If the process after
2746                        // it is for the same uid, however, don't do so, because we don't
2747                        // want them internally to be re-ordered.
2748                        if (mLruProcesses.get(i-1).info.uid != uid) {
2749                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2750                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2751                            ProcessRecord tmp = mLruProcesses.get(i);
2752                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2753                            mLruProcesses.set(i-1, tmp);
2754                            i--;
2755                        }
2756                    } else {
2757                        // A gap, we can stop here.
2758                        break;
2759                    }
2760                }
2761            } else {
2762                // Process has activities, put it at the very tipsy-top.
2763                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2764                mLruProcesses.add(app);
2765            }
2766            nextIndex = mLruProcessServiceStart;
2767        } else if (hasService) {
2768            // Process has services, put it at the top of the service list.
2769            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2770            mLruProcesses.add(mLruProcessActivityStart, app);
2771            nextIndex = mLruProcessServiceStart;
2772            mLruProcessActivityStart++;
2773        } else  {
2774            // Process not otherwise of interest, it goes to the top of the non-service area.
2775            int index = mLruProcessServiceStart;
2776            if (client != null) {
2777                // If there is a client, don't allow the process to be moved up higher
2778                // in the list than that client.
2779                int clientIndex = mLruProcesses.lastIndexOf(client);
2780                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2781                        + " when updating " + app);
2782                if (clientIndex <= lrui) {
2783                    // Don't allow the client index restriction to push it down farther in the
2784                    // list than it already is.
2785                    clientIndex = lrui;
2786                }
2787                if (clientIndex >= 0 && index > clientIndex) {
2788                    index = clientIndex;
2789                }
2790            }
2791            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2792            mLruProcesses.add(index, app);
2793            nextIndex = index-1;
2794            mLruProcessActivityStart++;
2795            mLruProcessServiceStart++;
2796        }
2797
2798        // If the app is currently using a content provider or service,
2799        // bump those processes as well.
2800        for (int j=app.connections.size()-1; j>=0; j--) {
2801            ConnectionRecord cr = app.connections.valueAt(j);
2802            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2803                    && cr.binding.service.app != null
2804                    && cr.binding.service.app.lruSeq != mLruSeq
2805                    && !cr.binding.service.app.persistent) {
2806                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2807                        "service connection", cr, app);
2808            }
2809        }
2810        for (int j=app.conProviders.size()-1; j>=0; j--) {
2811            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2812            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2813                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2814                        "provider reference", cpr, app);
2815            }
2816        }
2817    }
2818
2819    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2820        if (uid == Process.SYSTEM_UID) {
2821            // The system gets to run in any process.  If there are multiple
2822            // processes with the same uid, just pick the first (this
2823            // should never happen).
2824            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2825            if (procs == null) return null;
2826            final int N = procs.size();
2827            for (int i = 0; i < N; i++) {
2828                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2829            }
2830        }
2831        ProcessRecord proc = mProcessNames.get(processName, uid);
2832        if (false && proc != null && !keepIfLarge
2833                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2834                && proc.lastCachedPss >= 4000) {
2835            // Turn this condition on to cause killing to happen regularly, for testing.
2836            if (proc.baseProcessTracker != null) {
2837                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2838            }
2839            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2840        } else if (proc != null && !keepIfLarge
2841                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2842                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2843            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2844            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2845                if (proc.baseProcessTracker != null) {
2846                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2847                }
2848                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2849            }
2850        }
2851        return proc;
2852    }
2853
2854    void ensurePackageDexOpt(String packageName) {
2855        IPackageManager pm = AppGlobals.getPackageManager();
2856        try {
2857            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2858                mDidDexOpt = true;
2859            }
2860        } catch (RemoteException e) {
2861        }
2862    }
2863
2864    boolean isNextTransitionForward() {
2865        int transit = mWindowManager.getPendingAppTransition();
2866        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2867                || transit == AppTransition.TRANSIT_TASK_OPEN
2868                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2869    }
2870
2871    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2872            String processName, String abiOverride, int uid, Runnable crashHandler) {
2873        synchronized(this) {
2874            ApplicationInfo info = new ApplicationInfo();
2875            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2876            // For isolated processes, the former contains the parent's uid and the latter the
2877            // actual uid of the isolated process.
2878            // In the special case introduced by this method (which is, starting an isolated
2879            // process directly from the SystemServer without an actual parent app process) the
2880            // closest thing to a parent's uid is SYSTEM_UID.
2881            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2882            // the |isolated| logic in the ProcessRecord constructor.
2883            info.uid = Process.SYSTEM_UID;
2884            info.processName = processName;
2885            info.className = entryPoint;
2886            info.packageName = "android";
2887            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2888                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2889                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2890                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2891                    crashHandler);
2892            return proc != null ? proc.pid : 0;
2893        }
2894    }
2895
2896    final ProcessRecord startProcessLocked(String processName,
2897            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2898            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2899            boolean isolated, boolean keepIfLarge) {
2900        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2901                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2902                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2903                null /* crashHandler */);
2904    }
2905
2906    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2907            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2908            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2909            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2910        long startTime = SystemClock.elapsedRealtime();
2911        ProcessRecord app;
2912        if (!isolated) {
2913            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2914            checkTime(startTime, "startProcess: after getProcessRecord");
2915        } else {
2916            // If this is an isolated process, it can't re-use an existing process.
2917            app = null;
2918        }
2919        // We don't have to do anything more if:
2920        // (1) There is an existing application record; and
2921        // (2) The caller doesn't think it is dead, OR there is no thread
2922        //     object attached to it so we know it couldn't have crashed; and
2923        // (3) There is a pid assigned to it, so it is either starting or
2924        //     already running.
2925        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2926                + " app=" + app + " knownToBeDead=" + knownToBeDead
2927                + " thread=" + (app != null ? app.thread : null)
2928                + " pid=" + (app != null ? app.pid : -1));
2929        if (app != null && app.pid > 0) {
2930            if (!knownToBeDead || app.thread == null) {
2931                // We already have the app running, or are waiting for it to
2932                // come up (we have a pid but not yet its thread), so keep it.
2933                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2934                // If this is a new package in the process, add the package to the list
2935                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2936                checkTime(startTime, "startProcess: done, added package to proc");
2937                return app;
2938            }
2939
2940            // An application record is attached to a previous process,
2941            // clean it up now.
2942            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2943            checkTime(startTime, "startProcess: bad proc running, killing");
2944            Process.killProcessGroup(app.info.uid, app.pid);
2945            handleAppDiedLocked(app, true, true);
2946            checkTime(startTime, "startProcess: done killing old proc");
2947        }
2948
2949        String hostingNameStr = hostingName != null
2950                ? hostingName.flattenToShortString() : null;
2951
2952        if (!isolated) {
2953            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2954                // If we are in the background, then check to see if this process
2955                // is bad.  If so, we will just silently fail.
2956                if (mBadProcesses.get(info.processName, info.uid) != null) {
2957                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2958                            + "/" + info.processName);
2959                    return null;
2960                }
2961            } else {
2962                // When the user is explicitly starting a process, then clear its
2963                // crash count so that we won't make it bad until they see at
2964                // least one crash dialog again, and make the process good again
2965                // if it had been bad.
2966                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2967                        + "/" + info.processName);
2968                mProcessCrashTimes.remove(info.processName, info.uid);
2969                if (mBadProcesses.get(info.processName, info.uid) != null) {
2970                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2971                            UserHandle.getUserId(info.uid), info.uid,
2972                            info.processName);
2973                    mBadProcesses.remove(info.processName, info.uid);
2974                    if (app != null) {
2975                        app.bad = false;
2976                    }
2977                }
2978            }
2979        }
2980
2981        if (app == null) {
2982            checkTime(startTime, "startProcess: creating new process record");
2983            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2984            app.crashHandler = crashHandler;
2985            if (app == null) {
2986                Slog.w(TAG, "Failed making new process record for "
2987                        + processName + "/" + info.uid + " isolated=" + isolated);
2988                return null;
2989            }
2990            mProcessNames.put(processName, app.uid, app);
2991            if (isolated) {
2992                mIsolatedProcesses.put(app.uid, app);
2993            }
2994            checkTime(startTime, "startProcess: done creating new process record");
2995        } else {
2996            // If this is a new package in the process, add the package to the list
2997            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2998            checkTime(startTime, "startProcess: added package to existing proc");
2999        }
3000
3001        // If the system is not ready yet, then hold off on starting this
3002        // process until it is.
3003        if (!mProcessesReady
3004                && !isAllowedWhileBooting(info)
3005                && !allowWhileBooting) {
3006            if (!mProcessesOnHold.contains(app)) {
3007                mProcessesOnHold.add(app);
3008            }
3009            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
3010            checkTime(startTime, "startProcess: returning with proc on hold");
3011            return app;
3012        }
3013
3014        checkTime(startTime, "startProcess: stepping in to startProcess");
3015        startProcessLocked(
3016                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3017        checkTime(startTime, "startProcess: done starting proc!");
3018        return (app.pid != 0) ? app : null;
3019    }
3020
3021    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3022        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3023    }
3024
3025    private final void startProcessLocked(ProcessRecord app,
3026            String hostingType, String hostingNameStr) {
3027        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3028                null /* entryPoint */, null /* entryPointArgs */);
3029    }
3030
3031    private final void startProcessLocked(ProcessRecord app, String hostingType,
3032            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3033        long startTime = SystemClock.elapsedRealtime();
3034        if (app.pid > 0 && app.pid != MY_PID) {
3035            checkTime(startTime, "startProcess: removing from pids map");
3036            synchronized (mPidsSelfLocked) {
3037                mPidsSelfLocked.remove(app.pid);
3038                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3039            }
3040            checkTime(startTime, "startProcess: done removing from pids map");
3041            app.setPid(0);
3042        }
3043
3044        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3045                "startProcessLocked removing on hold: " + app);
3046        mProcessesOnHold.remove(app);
3047
3048        checkTime(startTime, "startProcess: starting to update cpu stats");
3049        updateCpuStats();
3050        checkTime(startTime, "startProcess: done updating cpu stats");
3051
3052        try {
3053            int uid = app.uid;
3054
3055            int[] gids = null;
3056            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3057            if (!app.isolated) {
3058                int[] permGids = null;
3059                try {
3060                    checkTime(startTime, "startProcess: getting gids from package manager");
3061                    final PackageManager pm = mContext.getPackageManager();
3062                    permGids = pm.getPackageGids(app.info.packageName);
3063
3064                    if (Environment.isExternalStorageEmulated()) {
3065                        checkTime(startTime, "startProcess: checking external storage perm");
3066                        if (pm.checkPermission(
3067                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3068                                app.info.packageName) == PERMISSION_GRANTED) {
3069                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3070                        } else {
3071                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3072                        }
3073                    }
3074                } catch (PackageManager.NameNotFoundException e) {
3075                    Slog.w(TAG, "Unable to retrieve gids", e);
3076                }
3077
3078                /*
3079                 * Add shared application and profile GIDs so applications can share some
3080                 * resources like shared libraries and access user-wide resources
3081                 */
3082                if (permGids == null) {
3083                    gids = new int[2];
3084                } else {
3085                    gids = new int[permGids.length + 2];
3086                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3087                }
3088                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3089                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3090            }
3091            checkTime(startTime, "startProcess: building args");
3092            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3093                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3094                        && mTopComponent != null
3095                        && app.processName.equals(mTopComponent.getPackageName())) {
3096                    uid = 0;
3097                }
3098                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3099                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3100                    uid = 0;
3101                }
3102            }
3103            int debugFlags = 0;
3104            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3105                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3106                // Also turn on CheckJNI for debuggable apps. It's quite
3107                // awkward to turn on otherwise.
3108                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3109            }
3110            // Run the app in safe mode if its manifest requests so or the
3111            // system is booted in safe mode.
3112            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3113                mSafeMode == true) {
3114                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3115            }
3116            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3117                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3118            }
3119            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3120                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3121            }
3122            if ("1".equals(SystemProperties.get("debug.assert"))) {
3123                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3124            }
3125
3126            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3127            if (requiredAbi == null) {
3128                requiredAbi = Build.SUPPORTED_ABIS[0];
3129            }
3130
3131            String instructionSet = null;
3132            if (app.info.primaryCpuAbi != null) {
3133                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3134            }
3135
3136            // Start the process.  It will either succeed and return a result containing
3137            // the PID of the new process, or else throw a RuntimeException.
3138            boolean isActivityProcess = (entryPoint == null);
3139            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3140            checkTime(startTime, "startProcess: asking zygote to start proc");
3141            Process.ProcessStartResult startResult = Process.start(entryPoint,
3142                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3143                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3144                    entryPointArgs);
3145            checkTime(startTime, "startProcess: returned from zygote!");
3146
3147            if (app.isolated) {
3148                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3149            }
3150            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3151            checkTime(startTime, "startProcess: done updating battery stats");
3152
3153            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3154                    UserHandle.getUserId(uid), startResult.pid, uid,
3155                    app.processName, hostingType,
3156                    hostingNameStr != null ? hostingNameStr : "");
3157
3158            if (app.persistent) {
3159                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3160            }
3161
3162            checkTime(startTime, "startProcess: building log message");
3163            StringBuilder buf = mStringBuilder;
3164            buf.setLength(0);
3165            buf.append("Start proc ");
3166            buf.append(app.processName);
3167            if (!isActivityProcess) {
3168                buf.append(" [");
3169                buf.append(entryPoint);
3170                buf.append("]");
3171            }
3172            buf.append(" for ");
3173            buf.append(hostingType);
3174            if (hostingNameStr != null) {
3175                buf.append(" ");
3176                buf.append(hostingNameStr);
3177            }
3178            buf.append(": pid=");
3179            buf.append(startResult.pid);
3180            buf.append(" uid=");
3181            buf.append(uid);
3182            buf.append(" gids={");
3183            if (gids != null) {
3184                for (int gi=0; gi<gids.length; gi++) {
3185                    if (gi != 0) buf.append(", ");
3186                    buf.append(gids[gi]);
3187
3188                }
3189            }
3190            buf.append("}");
3191            if (requiredAbi != null) {
3192                buf.append(" abi=");
3193                buf.append(requiredAbi);
3194            }
3195            Slog.i(TAG, buf.toString());
3196            app.setPid(startResult.pid);
3197            app.usingWrapper = startResult.usingWrapper;
3198            app.removed = false;
3199            app.killedByAm = false;
3200            checkTime(startTime, "startProcess: starting to update pids map");
3201            synchronized (mPidsSelfLocked) {
3202                this.mPidsSelfLocked.put(startResult.pid, app);
3203                if (isActivityProcess) {
3204                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3205                    msg.obj = app;
3206                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3207                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3208                }
3209            }
3210            checkTime(startTime, "startProcess: done updating pids map");
3211        } catch (RuntimeException e) {
3212            // XXX do better error recovery.
3213            app.setPid(0);
3214            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3215            if (app.isolated) {
3216                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3217            }
3218            Slog.e(TAG, "Failure starting process " + app.processName, e);
3219        }
3220    }
3221
3222    void updateUsageStats(ActivityRecord component, boolean resumed) {
3223        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3224        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3225        if (resumed) {
3226            if (mUsageStatsService != null) {
3227                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3228                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3229            }
3230            synchronized (stats) {
3231                stats.noteActivityResumedLocked(component.app.uid);
3232            }
3233        } else {
3234            if (mUsageStatsService != null) {
3235                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3236                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3237            }
3238            synchronized (stats) {
3239                stats.noteActivityPausedLocked(component.app.uid);
3240            }
3241        }
3242    }
3243
3244    Intent getHomeIntent() {
3245        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3246        intent.setComponent(mTopComponent);
3247        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3248            intent.addCategory(Intent.CATEGORY_HOME);
3249        }
3250        return intent;
3251    }
3252
3253    boolean startHomeActivityLocked(int userId) {
3254        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3255                && mTopAction == null) {
3256            // We are running in factory test mode, but unable to find
3257            // the factory test app, so just sit around displaying the
3258            // error message and don't try to start anything.
3259            return false;
3260        }
3261        Intent intent = getHomeIntent();
3262        ActivityInfo aInfo =
3263            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3264        if (aInfo != null) {
3265            intent.setComponent(new ComponentName(
3266                    aInfo.applicationInfo.packageName, aInfo.name));
3267            // Don't do this if the home app is currently being
3268            // instrumented.
3269            aInfo = new ActivityInfo(aInfo);
3270            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3271            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3272                    aInfo.applicationInfo.uid, true);
3273            if (app == null || app.instrumentationClass == null) {
3274                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3275                mStackSupervisor.startHomeActivity(intent, aInfo);
3276            }
3277        }
3278
3279        return true;
3280    }
3281
3282    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3283        ActivityInfo ai = null;
3284        ComponentName comp = intent.getComponent();
3285        try {
3286            if (comp != null) {
3287                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3288            } else {
3289                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3290                        intent,
3291                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3292                            flags, userId);
3293
3294                if (info != null) {
3295                    ai = info.activityInfo;
3296                }
3297            }
3298        } catch (RemoteException e) {
3299            // ignore
3300        }
3301
3302        return ai;
3303    }
3304
3305    /**
3306     * Starts the "new version setup screen" if appropriate.
3307     */
3308    void startSetupActivityLocked() {
3309        // Only do this once per boot.
3310        if (mCheckedForSetup) {
3311            return;
3312        }
3313
3314        // We will show this screen if the current one is a different
3315        // version than the last one shown, and we are not running in
3316        // low-level factory test mode.
3317        final ContentResolver resolver = mContext.getContentResolver();
3318        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3319                Settings.Global.getInt(resolver,
3320                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3321            mCheckedForSetup = true;
3322
3323            // See if we should be showing the platform update setup UI.
3324            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3325            List<ResolveInfo> ris = mContext.getPackageManager()
3326                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3327
3328            // We don't allow third party apps to replace this.
3329            ResolveInfo ri = null;
3330            for (int i=0; ris != null && i<ris.size(); i++) {
3331                if ((ris.get(i).activityInfo.applicationInfo.flags
3332                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3333                    ri = ris.get(i);
3334                    break;
3335                }
3336            }
3337
3338            if (ri != null) {
3339                String vers = ri.activityInfo.metaData != null
3340                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3341                        : null;
3342                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3343                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3344                            Intent.METADATA_SETUP_VERSION);
3345                }
3346                String lastVers = Settings.Secure.getString(
3347                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3348                if (vers != null && !vers.equals(lastVers)) {
3349                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3350                    intent.setComponent(new ComponentName(
3351                            ri.activityInfo.packageName, ri.activityInfo.name));
3352                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3353                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null,
3354                            null);
3355                }
3356            }
3357        }
3358    }
3359
3360    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3361        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3362    }
3363
3364    void enforceNotIsolatedCaller(String caller) {
3365        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3366            throw new SecurityException("Isolated process not allowed to call " + caller);
3367        }
3368    }
3369
3370    @Override
3371    public int getFrontActivityScreenCompatMode() {
3372        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3373        synchronized (this) {
3374            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3375        }
3376    }
3377
3378    @Override
3379    public void setFrontActivityScreenCompatMode(int mode) {
3380        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3381                "setFrontActivityScreenCompatMode");
3382        synchronized (this) {
3383            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3384        }
3385    }
3386
3387    @Override
3388    public int getPackageScreenCompatMode(String packageName) {
3389        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3390        synchronized (this) {
3391            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3392        }
3393    }
3394
3395    @Override
3396    public void setPackageScreenCompatMode(String packageName, int mode) {
3397        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3398                "setPackageScreenCompatMode");
3399        synchronized (this) {
3400            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3401        }
3402    }
3403
3404    @Override
3405    public boolean getPackageAskScreenCompat(String packageName) {
3406        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3407        synchronized (this) {
3408            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3409        }
3410    }
3411
3412    @Override
3413    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3414        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3415                "setPackageAskScreenCompat");
3416        synchronized (this) {
3417            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3418        }
3419    }
3420
3421    private void dispatchProcessesChanged() {
3422        int N;
3423        synchronized (this) {
3424            N = mPendingProcessChanges.size();
3425            if (mActiveProcessChanges.length < N) {
3426                mActiveProcessChanges = new ProcessChangeItem[N];
3427            }
3428            mPendingProcessChanges.toArray(mActiveProcessChanges);
3429            mAvailProcessChanges.addAll(mPendingProcessChanges);
3430            mPendingProcessChanges.clear();
3431            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3432        }
3433
3434        int i = mProcessObservers.beginBroadcast();
3435        while (i > 0) {
3436            i--;
3437            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3438            if (observer != null) {
3439                try {
3440                    for (int j=0; j<N; j++) {
3441                        ProcessChangeItem item = mActiveProcessChanges[j];
3442                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3443                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3444                                    + item.pid + " uid=" + item.uid + ": "
3445                                    + item.foregroundActivities);
3446                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3447                                    item.foregroundActivities);
3448                        }
3449                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3450                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3451                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3452                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3453                        }
3454                    }
3455                } catch (RemoteException e) {
3456                }
3457            }
3458        }
3459        mProcessObservers.finishBroadcast();
3460    }
3461
3462    private void dispatchProcessDied(int pid, int uid) {
3463        int i = mProcessObservers.beginBroadcast();
3464        while (i > 0) {
3465            i--;
3466            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3467            if (observer != null) {
3468                try {
3469                    observer.onProcessDied(pid, uid);
3470                } catch (RemoteException e) {
3471                }
3472            }
3473        }
3474        mProcessObservers.finishBroadcast();
3475    }
3476
3477    @Override
3478    public final int startActivity(IApplicationThread caller, String callingPackage,
3479            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3480            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3481        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3482            resultWho, requestCode, startFlags, profilerInfo, options,
3483            UserHandle.getCallingUserId());
3484    }
3485
3486    @Override
3487    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3488            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3489            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3490        enforceNotIsolatedCaller("startActivity");
3491        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3492                false, ALLOW_FULL_ONLY, "startActivity", null);
3493        // TODO: Switch to user app stacks here.
3494        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3495                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3496                profilerInfo, null, null, options, userId, null, null);
3497    }
3498
3499    @Override
3500    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3501            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3502            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3503
3504        // This is very dangerous -- it allows you to perform a start activity (including
3505        // permission grants) as any app that may launch one of your own activities.  So
3506        // we will only allow this to be done from activities that are part of the core framework,
3507        // and then only when they are running as the system.
3508        final ActivityRecord sourceRecord;
3509        final int targetUid;
3510        final String targetPackage;
3511        synchronized (this) {
3512            if (resultTo == null) {
3513                throw new SecurityException("Must be called from an activity");
3514            }
3515            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3516            if (sourceRecord == null) {
3517                throw new SecurityException("Called with bad activity token: " + resultTo);
3518            }
3519            if (!sourceRecord.info.packageName.equals("android")) {
3520                throw new SecurityException(
3521                        "Must be called from an activity that is declared in the android package");
3522            }
3523            if (sourceRecord.app == null) {
3524                throw new SecurityException("Called without a process attached to activity");
3525            }
3526            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3527                // This is still okay, as long as this activity is running under the
3528                // uid of the original calling activity.
3529                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3530                    throw new SecurityException(
3531                            "Calling activity in uid " + sourceRecord.app.uid
3532                                    + " must be system uid or original calling uid "
3533                                    + sourceRecord.launchedFromUid);
3534                }
3535            }
3536            targetUid = sourceRecord.launchedFromUid;
3537            targetPackage = sourceRecord.launchedFromPackage;
3538        }
3539
3540        // TODO: Switch to user app stacks here.
3541        try {
3542            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3543                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3544                    null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null);
3545            return ret;
3546        } catch (SecurityException e) {
3547            // XXX need to figure out how to propagate to original app.
3548            // A SecurityException here is generally actually a fault of the original
3549            // calling activity (such as a fairly granting permissions), so propagate it
3550            // back to them.
3551            /*
3552            StringBuilder msg = new StringBuilder();
3553            msg.append("While launching");
3554            msg.append(intent.toString());
3555            msg.append(": ");
3556            msg.append(e.getMessage());
3557            */
3558            throw e;
3559        }
3560    }
3561
3562    @Override
3563    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3564            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3565            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3566        enforceNotIsolatedCaller("startActivityAndWait");
3567        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3568                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3569        WaitResult res = new WaitResult();
3570        // TODO: Switch to user app stacks here.
3571        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3572                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3573                options, userId, null, null);
3574        return res;
3575    }
3576
3577    @Override
3578    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3579            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3580            int startFlags, Configuration config, Bundle options, int userId) {
3581        enforceNotIsolatedCaller("startActivityWithConfig");
3582        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3583                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3584        // TODO: Switch to user app stacks here.
3585        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3586                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3587                null, null, config, options, userId, null, null);
3588        return ret;
3589    }
3590
3591    @Override
3592    public int startActivityIntentSender(IApplicationThread caller,
3593            IntentSender intent, Intent fillInIntent, String resolvedType,
3594            IBinder resultTo, String resultWho, int requestCode,
3595            int flagsMask, int flagsValues, Bundle options) {
3596        enforceNotIsolatedCaller("startActivityIntentSender");
3597        // Refuse possible leaked file descriptors
3598        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3599            throw new IllegalArgumentException("File descriptors passed in Intent");
3600        }
3601
3602        IIntentSender sender = intent.getTarget();
3603        if (!(sender instanceof PendingIntentRecord)) {
3604            throw new IllegalArgumentException("Bad PendingIntent object");
3605        }
3606
3607        PendingIntentRecord pir = (PendingIntentRecord)sender;
3608
3609        synchronized (this) {
3610            // If this is coming from the currently resumed activity, it is
3611            // effectively saying that app switches are allowed at this point.
3612            final ActivityStack stack = getFocusedStack();
3613            if (stack.mResumedActivity != null &&
3614                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3615                mAppSwitchesAllowedTime = 0;
3616            }
3617        }
3618        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3619                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3620        return ret;
3621    }
3622
3623    @Override
3624    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3625            Intent intent, String resolvedType, IVoiceInteractionSession session,
3626            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3627            Bundle options, int userId) {
3628        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3629                != PackageManager.PERMISSION_GRANTED) {
3630            String msg = "Permission Denial: startVoiceActivity() from pid="
3631                    + Binder.getCallingPid()
3632                    + ", uid=" + Binder.getCallingUid()
3633                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3634            Slog.w(TAG, msg);
3635            throw new SecurityException(msg);
3636        }
3637        if (session == null || interactor == null) {
3638            throw new NullPointerException("null session or interactor");
3639        }
3640        userId = handleIncomingUser(callingPid, callingUid, userId,
3641                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3642        // TODO: Switch to user app stacks here.
3643        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3644                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3645                null, options, userId, null, null);
3646    }
3647
3648    @Override
3649    public boolean startNextMatchingActivity(IBinder callingActivity,
3650            Intent intent, Bundle options) {
3651        // Refuse possible leaked file descriptors
3652        if (intent != null && intent.hasFileDescriptors() == true) {
3653            throw new IllegalArgumentException("File descriptors passed in Intent");
3654        }
3655
3656        synchronized (this) {
3657            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3658            if (r == null) {
3659                ActivityOptions.abort(options);
3660                return false;
3661            }
3662            if (r.app == null || r.app.thread == null) {
3663                // The caller is not running...  d'oh!
3664                ActivityOptions.abort(options);
3665                return false;
3666            }
3667            intent = new Intent(intent);
3668            // The caller is not allowed to change the data.
3669            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3670            // And we are resetting to find the next component...
3671            intent.setComponent(null);
3672
3673            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3674
3675            ActivityInfo aInfo = null;
3676            try {
3677                List<ResolveInfo> resolves =
3678                    AppGlobals.getPackageManager().queryIntentActivities(
3679                            intent, r.resolvedType,
3680                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3681                            UserHandle.getCallingUserId());
3682
3683                // Look for the original activity in the list...
3684                final int N = resolves != null ? resolves.size() : 0;
3685                for (int i=0; i<N; i++) {
3686                    ResolveInfo rInfo = resolves.get(i);
3687                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3688                            && rInfo.activityInfo.name.equals(r.info.name)) {
3689                        // We found the current one...  the next matching is
3690                        // after it.
3691                        i++;
3692                        if (i<N) {
3693                            aInfo = resolves.get(i).activityInfo;
3694                        }
3695                        if (debug) {
3696                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3697                                    + "/" + r.info.name);
3698                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3699                                    + "/" + aInfo.name);
3700                        }
3701                        break;
3702                    }
3703                }
3704            } catch (RemoteException e) {
3705            }
3706
3707            if (aInfo == null) {
3708                // Nobody who is next!
3709                ActivityOptions.abort(options);
3710                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3711                return false;
3712            }
3713
3714            intent.setComponent(new ComponentName(
3715                    aInfo.applicationInfo.packageName, aInfo.name));
3716            intent.setFlags(intent.getFlags()&~(
3717                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3718                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3719                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3720                    Intent.FLAG_ACTIVITY_NEW_TASK));
3721
3722            // Okay now we need to start the new activity, replacing the
3723            // currently running activity.  This is a little tricky because
3724            // we want to start the new one as if the current one is finished,
3725            // but not finish the current one first so that there is no flicker.
3726            // And thus...
3727            final boolean wasFinishing = r.finishing;
3728            r.finishing = true;
3729
3730            // Propagate reply information over to the new activity.
3731            final ActivityRecord resultTo = r.resultTo;
3732            final String resultWho = r.resultWho;
3733            final int requestCode = r.requestCode;
3734            r.resultTo = null;
3735            if (resultTo != null) {
3736                resultTo.removeResultsLocked(r, resultWho, requestCode);
3737            }
3738
3739            final long origId = Binder.clearCallingIdentity();
3740            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3741                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3742                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3743                    options, false, null, null, null);
3744            Binder.restoreCallingIdentity(origId);
3745
3746            r.finishing = wasFinishing;
3747            if (res != ActivityManager.START_SUCCESS) {
3748                return false;
3749            }
3750            return true;
3751        }
3752    }
3753
3754    @Override
3755    public final int startActivityFromRecents(int taskId, Bundle options) {
3756        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3757            String msg = "Permission Denial: startActivityFromRecents called without " +
3758                    START_TASKS_FROM_RECENTS;
3759            Slog.w(TAG, msg);
3760            throw new SecurityException(msg);
3761        }
3762        return startActivityFromRecentsInner(taskId, options);
3763    }
3764
3765    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3766        final TaskRecord task;
3767        final int callingUid;
3768        final String callingPackage;
3769        final Intent intent;
3770        final int userId;
3771        synchronized (this) {
3772            task = recentTaskForIdLocked(taskId);
3773            if (task == null) {
3774                throw new IllegalArgumentException("Task " + taskId + " not found.");
3775            }
3776            callingUid = task.mCallingUid;
3777            callingPackage = task.mCallingPackage;
3778            intent = task.intent;
3779            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3780            userId = task.userId;
3781        }
3782        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3783                options, userId, null, task);
3784    }
3785
3786    final int startActivityInPackage(int uid, String callingPackage,
3787            Intent intent, String resolvedType, IBinder resultTo,
3788            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3789            IActivityContainer container, TaskRecord inTask) {
3790
3791        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3792                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3793
3794        // TODO: Switch to user app stacks here.
3795        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3796                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3797                null, null, null, options, userId, container, inTask);
3798        return ret;
3799    }
3800
3801    @Override
3802    public final int startActivities(IApplicationThread caller, String callingPackage,
3803            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3804            int userId) {
3805        enforceNotIsolatedCaller("startActivities");
3806        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3807                false, ALLOW_FULL_ONLY, "startActivity", null);
3808        // TODO: Switch to user app stacks here.
3809        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3810                resolvedTypes, resultTo, options, userId);
3811        return ret;
3812    }
3813
3814    final int startActivitiesInPackage(int uid, String callingPackage,
3815            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3816            Bundle options, int userId) {
3817
3818        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3819                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3820        // TODO: Switch to user app stacks here.
3821        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3822                resultTo, options, userId);
3823        return ret;
3824    }
3825
3826    //explicitly remove thd old information in mRecentTasks when removing existing user.
3827    private void removeRecentTasksForUserLocked(int userId) {
3828        if(userId <= 0) {
3829            Slog.i(TAG, "Can't remove recent task on user " + userId);
3830            return;
3831        }
3832
3833        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3834            TaskRecord tr = mRecentTasks.get(i);
3835            if (tr.userId == userId) {
3836                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3837                        + " when finishing user" + userId);
3838                mRecentTasks.remove(i);
3839                tr.removedFromRecents(mTaskPersister);
3840            }
3841        }
3842
3843        // Remove tasks from persistent storage.
3844        mTaskPersister.wakeup(null, true);
3845    }
3846
3847    /**
3848     * Update the recent tasks lists: make sure tasks should still be here (their
3849     * applications / activities still exist), update their availability, fixup ordering
3850     * of affiliations.
3851     */
3852    void cleanupRecentTasksLocked(int userId) {
3853        if (mRecentTasks == null) {
3854            // Happens when called from the packagemanager broadcast before boot.
3855            return;
3856        }
3857
3858        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3859        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3860        final IPackageManager pm = AppGlobals.getPackageManager();
3861        final ActivityInfo dummyAct = new ActivityInfo();
3862        final ApplicationInfo dummyApp = new ApplicationInfo();
3863
3864        int N = mRecentTasks.size();
3865
3866        int[] users = userId == UserHandle.USER_ALL
3867                ? getUsersLocked() : new int[] { userId };
3868        for (int user : users) {
3869            for (int i = 0; i < N; i++) {
3870                TaskRecord task = mRecentTasks.get(i);
3871                if (task.userId != user) {
3872                    // Only look at tasks for the user ID of interest.
3873                    continue;
3874                }
3875                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3876                    // This situation is broken, and we should just get rid of it now.
3877                    mRecentTasks.remove(i);
3878                    task.removedFromRecents(mTaskPersister);
3879                    i--;
3880                    N--;
3881                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3882                    continue;
3883                }
3884                // Check whether this activity is currently available.
3885                if (task.realActivity != null) {
3886                    ActivityInfo ai = availActCache.get(task.realActivity);
3887                    if (ai == null) {
3888                        try {
3889                            ai = pm.getActivityInfo(task.realActivity,
3890                                    PackageManager.GET_UNINSTALLED_PACKAGES
3891                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3892                        } catch (RemoteException e) {
3893                            // Will never happen.
3894                            continue;
3895                        }
3896                        if (ai == null) {
3897                            ai = dummyAct;
3898                        }
3899                        availActCache.put(task.realActivity, ai);
3900                    }
3901                    if (ai == dummyAct) {
3902                        // This could be either because the activity no longer exists, or the
3903                        // app is temporarily gone.  For the former we want to remove the recents
3904                        // entry; for the latter we want to mark it as unavailable.
3905                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3906                        if (app == null) {
3907                            try {
3908                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3909                                        PackageManager.GET_UNINSTALLED_PACKAGES
3910                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3911                            } catch (RemoteException e) {
3912                                // Will never happen.
3913                                continue;
3914                            }
3915                            if (app == null) {
3916                                app = dummyApp;
3917                            }
3918                            availAppCache.put(task.realActivity.getPackageName(), app);
3919                        }
3920                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3921                            // Doesn't exist any more!  Good-bye.
3922                            mRecentTasks.remove(i);
3923                            task.removedFromRecents(mTaskPersister);
3924                            i--;
3925                            N--;
3926                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3927                            continue;
3928                        } else {
3929                            // Otherwise just not available for now.
3930                            if (task.isAvailable) {
3931                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3932                                        + task);
3933                            }
3934                            task.isAvailable = false;
3935                        }
3936                    } else {
3937                        if (!ai.enabled || !ai.applicationInfo.enabled
3938                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3939                            if (task.isAvailable) {
3940                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3941                                        + task + " (enabled=" + ai.enabled + "/"
3942                                        + ai.applicationInfo.enabled +  " flags="
3943                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3944                            }
3945                            task.isAvailable = false;
3946                        } else {
3947                            if (!task.isAvailable) {
3948                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3949                                        + task);
3950                            }
3951                            task.isAvailable = true;
3952                        }
3953                    }
3954                }
3955            }
3956        }
3957
3958        // Verify the affiliate chain for each task.
3959        for (int i = 0; i < N; ) {
3960            TaskRecord task = mRecentTasks.remove(i);
3961            if (mTmpRecents.contains(task)) {
3962                continue;
3963            }
3964            int affiliatedTaskId = task.mAffiliatedTaskId;
3965            while (true) {
3966                TaskRecord next = task.mNextAffiliate;
3967                if (next == null) {
3968                    break;
3969                }
3970                if (next.mAffiliatedTaskId != affiliatedTaskId) {
3971                    Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
3972                            next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
3973                    task.setNextAffiliate(null);
3974                    if (next.mPrevAffiliate == task) {
3975                        next.setPrevAffiliate(null);
3976                    }
3977                    break;
3978                }
3979                if (next.mPrevAffiliate != task) {
3980                    Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
3981                            next.mPrevAffiliate + " task=" + task);
3982                    next.setPrevAffiliate(null);
3983                    task.setNextAffiliate(null);
3984                    break;
3985                }
3986                if (!mRecentTasks.contains(next)) {
3987                    Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
3988                    task.setNextAffiliate(null);
3989                    // We know that next.mPrevAffiliate is always task, from above, so clear
3990                    // its previous affiliate.
3991                    next.setPrevAffiliate(null);
3992                    break;
3993                }
3994                task = next;
3995            }
3996            // task is now the end of the list
3997            do {
3998                mRecentTasks.remove(task);
3999                mRecentTasks.add(i++, task);
4000                mTmpRecents.add(task);
4001                task.inRecents = true;
4002            } while ((task = task.mPrevAffiliate) != null);
4003        }
4004        mTmpRecents.clear();
4005        // mRecentTasks is now in sorted, affiliated order.
4006    }
4007
4008    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
4009        int N = mRecentTasks.size();
4010        TaskRecord top = task;
4011        int topIndex = taskIndex;
4012        while (top.mNextAffiliate != null && topIndex > 0) {
4013            top = top.mNextAffiliate;
4014            topIndex--;
4015        }
4016        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
4017                + topIndex + " from intial " + taskIndex);
4018        // Find the end of the chain, doing a sanity check along the way.
4019        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
4020        int endIndex = topIndex;
4021        TaskRecord prev = top;
4022        while (endIndex < N) {
4023            TaskRecord cur = mRecentTasks.get(endIndex);
4024            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
4025                    + endIndex + " " + cur);
4026            if (cur == top) {
4027                // Verify start of the chain.
4028                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
4029                    Slog.wtf(TAG, "Bad chain @" + endIndex
4030                            + ": first task has next affiliate: " + prev);
4031                    sane = false;
4032                    break;
4033                }
4034            } else {
4035                // Verify middle of the chain's next points back to the one before.
4036                if (cur.mNextAffiliate != prev
4037                        || cur.mNextAffiliateTaskId != prev.taskId) {
4038                    Slog.wtf(TAG, "Bad chain @" + endIndex
4039                            + ": middle task " + cur + " @" + endIndex
4040                            + " has bad next affiliate "
4041                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
4042                            + ", expected " + prev);
4043                    sane = false;
4044                    break;
4045                }
4046            }
4047            if (cur.mPrevAffiliateTaskId == -1) {
4048                // Chain ends here.
4049                if (cur.mPrevAffiliate != null) {
4050                    Slog.wtf(TAG, "Bad chain @" + endIndex
4051                            + ": last task " + cur + " has previous affiliate "
4052                            + cur.mPrevAffiliate);
4053                    sane = false;
4054                }
4055                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
4056                break;
4057            } else {
4058                // Verify middle of the chain's prev points to a valid item.
4059                if (cur.mPrevAffiliate == null) {
4060                    Slog.wtf(TAG, "Bad chain @" + endIndex
4061                            + ": task " + cur + " has previous affiliate "
4062                            + cur.mPrevAffiliate + " but should be id "
4063                            + cur.mPrevAffiliate);
4064                    sane = false;
4065                    break;
4066                }
4067            }
4068            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
4069                Slog.wtf(TAG, "Bad chain @" + endIndex
4070                        + ": task " + cur + " has affiliated id "
4071                        + cur.mAffiliatedTaskId + " but should be "
4072                        + task.mAffiliatedTaskId);
4073                sane = false;
4074                break;
4075            }
4076            prev = cur;
4077            endIndex++;
4078            if (endIndex >= N) {
4079                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4080                        + ": last task " + prev);
4081                sane = false;
4082                break;
4083            }
4084        }
4085        if (sane) {
4086            if (endIndex < taskIndex) {
4087                Slog.wtf(TAG, "Bad chain @" + endIndex
4088                        + ": did not extend to task " + task + " @" + taskIndex);
4089                sane = false;
4090            }
4091        }
4092        if (sane) {
4093            // All looks good, we can just move all of the affiliated tasks
4094            // to the top.
4095            for (int i=topIndex; i<=endIndex; i++) {
4096                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4097                        + " from " + i + " to " + (i-topIndex));
4098                TaskRecord cur = mRecentTasks.remove(i);
4099                mRecentTasks.add(i-topIndex, cur);
4100            }
4101            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4102                    + " to " + endIndex);
4103            return true;
4104        }
4105
4106        // Whoops, couldn't do it.
4107        return false;
4108    }
4109
4110    final void addRecentTaskLocked(TaskRecord task) {
4111        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4112                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4113
4114        int N = mRecentTasks.size();
4115        // Quick case: check if the top-most recent task is the same.
4116        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4117            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4118            return;
4119        }
4120        // Another quick case: check if this is part of a set of affiliated
4121        // tasks that are at the top.
4122        if (isAffiliated && N > 0 && task.inRecents
4123                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4124            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4125                    + " at top when adding " + task);
4126            return;
4127        }
4128        // Another quick case: never add voice sessions.
4129        if (task.voiceSession != null) {
4130            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4131            return;
4132        }
4133
4134        boolean needAffiliationFix = false;
4135
4136        // Slightly less quick case: the task is already in recents, so all we need
4137        // to do is move it.
4138        if (task.inRecents) {
4139            int taskIndex = mRecentTasks.indexOf(task);
4140            if (taskIndex >= 0) {
4141                if (!isAffiliated) {
4142                    // Simple case: this is not an affiliated task, so we just move it to the front.
4143                    mRecentTasks.remove(taskIndex);
4144                    mRecentTasks.add(0, task);
4145                    notifyTaskPersisterLocked(task, false);
4146                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4147                            + " from " + taskIndex);
4148                    return;
4149                } else {
4150                    // More complicated: need to keep all affiliated tasks together.
4151                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4152                        // All went well.
4153                        return;
4154                    }
4155
4156                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4157                    // everything and then go through our general path of adding a new task.
4158                    needAffiliationFix = true;
4159                }
4160            } else {
4161                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4162                needAffiliationFix = true;
4163            }
4164        }
4165
4166        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4167        trimRecentsForTask(task, true);
4168
4169        N = mRecentTasks.size();
4170        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4171            final TaskRecord tr = mRecentTasks.remove(N - 1);
4172            tr.removedFromRecents(mTaskPersister);
4173            N--;
4174        }
4175        task.inRecents = true;
4176        if (!isAffiliated || needAffiliationFix) {
4177            // If this is a simple non-affiliated task, or we had some failure trying to
4178            // handle it as part of an affilated task, then just place it at the top.
4179            mRecentTasks.add(0, task);
4180        } else if (isAffiliated) {
4181            // If this is a new affiliated task, then move all of the affiliated tasks
4182            // to the front and insert this new one.
4183            TaskRecord other = task.mNextAffiliate;
4184            if (other == null) {
4185                other = task.mPrevAffiliate;
4186            }
4187            if (other != null) {
4188                int otherIndex = mRecentTasks.indexOf(other);
4189                if (otherIndex >= 0) {
4190                    // Insert new task at appropriate location.
4191                    int taskIndex;
4192                    if (other == task.mNextAffiliate) {
4193                        // We found the index of our next affiliation, which is who is
4194                        // before us in the list, so add after that point.
4195                        taskIndex = otherIndex+1;
4196                    } else {
4197                        // We found the index of our previous affiliation, which is who is
4198                        // after us in the list, so add at their position.
4199                        taskIndex = otherIndex;
4200                    }
4201                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4202                            + taskIndex + ": " + task);
4203                    mRecentTasks.add(taskIndex, task);
4204
4205                    // Now move everything to the front.
4206                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4207                        // All went well.
4208                        return;
4209                    }
4210
4211                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4212                    // everything and then go through our general path of adding a new task.
4213                    needAffiliationFix = true;
4214                } else {
4215                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4216                            + other);
4217                    needAffiliationFix = true;
4218                }
4219            } else {
4220                if (DEBUG_RECENTS) Slog.d(TAG,
4221                        "addRecent: adding affiliated task without next/prev:" + task);
4222                needAffiliationFix = true;
4223            }
4224        }
4225        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4226
4227        if (needAffiliationFix) {
4228            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4229            cleanupRecentTasksLocked(task.userId);
4230        }
4231    }
4232
4233    /**
4234     * If needed, remove oldest existing entries in recents that are for the same kind
4235     * of task as the given one.
4236     */
4237    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4238        int N = mRecentTasks.size();
4239        final Intent intent = task.intent;
4240        final boolean document = intent != null && intent.isDocument();
4241
4242        int maxRecents = task.maxRecents - 1;
4243        for (int i=0; i<N; i++) {
4244            final TaskRecord tr = mRecentTasks.get(i);
4245            if (task != tr) {
4246                if (task.userId != tr.userId) {
4247                    continue;
4248                }
4249                if (i > MAX_RECENT_BITMAPS) {
4250                    tr.freeLastThumbnail();
4251                }
4252                final Intent trIntent = tr.intent;
4253                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4254                    (intent == null || !intent.filterEquals(trIntent))) {
4255                    continue;
4256                }
4257                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4258                if (document && trIsDocument) {
4259                    // These are the same document activity (not necessarily the same doc).
4260                    if (maxRecents > 0) {
4261                        --maxRecents;
4262                        continue;
4263                    }
4264                    // Hit the maximum number of documents for this task. Fall through
4265                    // and remove this document from recents.
4266                } else if (document || trIsDocument) {
4267                    // Only one of these is a document. Not the droid we're looking for.
4268                    continue;
4269                }
4270            }
4271
4272            if (!doTrim) {
4273                // If the caller is not actually asking for a trim, just tell them we reached
4274                // a point where the trim would happen.
4275                return i;
4276            }
4277
4278            // Either task and tr are the same or, their affinities match or their intents match
4279            // and neither of them is a document, or they are documents using the same activity
4280            // and their maxRecents has been reached.
4281            tr.disposeThumbnail();
4282            mRecentTasks.remove(i);
4283            if (task != tr) {
4284                tr.removedFromRecents(mTaskPersister);
4285            }
4286            i--;
4287            N--;
4288            if (task.intent == null) {
4289                // If the new recent task we are adding is not fully
4290                // specified, then replace it with the existing recent task.
4291                task = tr;
4292            }
4293            notifyTaskPersisterLocked(tr, false);
4294        }
4295
4296        return -1;
4297    }
4298
4299    @Override
4300    public void reportActivityFullyDrawn(IBinder token) {
4301        synchronized (this) {
4302            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4303            if (r == null) {
4304                return;
4305            }
4306            r.reportFullyDrawnLocked();
4307        }
4308    }
4309
4310    @Override
4311    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4312        synchronized (this) {
4313            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4314            if (r == null) {
4315                return;
4316            }
4317            final long origId = Binder.clearCallingIdentity();
4318            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4319            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4320                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4321            if (config != null) {
4322                r.frozenBeforeDestroy = true;
4323                if (!updateConfigurationLocked(config, r, false, false)) {
4324                    mStackSupervisor.resumeTopActivitiesLocked();
4325                }
4326            }
4327            Binder.restoreCallingIdentity(origId);
4328        }
4329    }
4330
4331    @Override
4332    public int getRequestedOrientation(IBinder token) {
4333        synchronized (this) {
4334            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4335            if (r == null) {
4336                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4337            }
4338            return mWindowManager.getAppOrientation(r.appToken);
4339        }
4340    }
4341
4342    /**
4343     * This is the internal entry point for handling Activity.finish().
4344     *
4345     * @param token The Binder token referencing the Activity we want to finish.
4346     * @param resultCode Result code, if any, from this Activity.
4347     * @param resultData Result data (Intent), if any, from this Activity.
4348     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4349     *            the root Activity in the task.
4350     *
4351     * @return Returns true if the activity successfully finished, or false if it is still running.
4352     */
4353    @Override
4354    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4355            boolean finishTask) {
4356        // Refuse possible leaked file descriptors
4357        if (resultData != null && resultData.hasFileDescriptors() == true) {
4358            throw new IllegalArgumentException("File descriptors passed in Intent");
4359        }
4360
4361        synchronized(this) {
4362            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4363            if (r == null) {
4364                return true;
4365            }
4366            // Keep track of the root activity of the task before we finish it
4367            TaskRecord tr = r.task;
4368            ActivityRecord rootR = tr.getRootActivity();
4369            // Do not allow task to finish in Lock Task mode.
4370            if (tr == mStackSupervisor.mLockTaskModeTask) {
4371                if (rootR == r) {
4372                    mStackSupervisor.showLockTaskToast();
4373                    return false;
4374                }
4375            }
4376            if (mController != null) {
4377                // Find the first activity that is not finishing.
4378                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4379                if (next != null) {
4380                    // ask watcher if this is allowed
4381                    boolean resumeOK = true;
4382                    try {
4383                        resumeOK = mController.activityResuming(next.packageName);
4384                    } catch (RemoteException e) {
4385                        mController = null;
4386                        Watchdog.getInstance().setActivityController(null);
4387                    }
4388
4389                    if (!resumeOK) {
4390                        return false;
4391                    }
4392                }
4393            }
4394            final long origId = Binder.clearCallingIdentity();
4395            try {
4396                boolean res;
4397                if (finishTask && r == rootR) {
4398                    // If requested, remove the task that is associated to this activity only if it
4399                    // was the root activity in the task.  The result code and data is ignored because
4400                    // we don't support returning them across task boundaries.
4401                    res = removeTaskByIdLocked(tr.taskId, 0);
4402                } else {
4403                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4404                            resultData, "app-request", true);
4405                }
4406                return res;
4407            } finally {
4408                Binder.restoreCallingIdentity(origId);
4409            }
4410        }
4411    }
4412
4413    @Override
4414    public final void finishHeavyWeightApp() {
4415        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4416                != PackageManager.PERMISSION_GRANTED) {
4417            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4418                    + Binder.getCallingPid()
4419                    + ", uid=" + Binder.getCallingUid()
4420                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4421            Slog.w(TAG, msg);
4422            throw new SecurityException(msg);
4423        }
4424
4425        synchronized(this) {
4426            if (mHeavyWeightProcess == null) {
4427                return;
4428            }
4429
4430            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4431                    mHeavyWeightProcess.activities);
4432            for (int i=0; i<activities.size(); i++) {
4433                ActivityRecord r = activities.get(i);
4434                if (!r.finishing) {
4435                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4436                            null, "finish-heavy", true);
4437                }
4438            }
4439
4440            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4441                    mHeavyWeightProcess.userId, 0));
4442            mHeavyWeightProcess = null;
4443        }
4444    }
4445
4446    @Override
4447    public void crashApplication(int uid, int initialPid, String packageName,
4448            String message) {
4449        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4450                != PackageManager.PERMISSION_GRANTED) {
4451            String msg = "Permission Denial: crashApplication() from pid="
4452                    + Binder.getCallingPid()
4453                    + ", uid=" + Binder.getCallingUid()
4454                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4455            Slog.w(TAG, msg);
4456            throw new SecurityException(msg);
4457        }
4458
4459        synchronized(this) {
4460            ProcessRecord proc = null;
4461
4462            // Figure out which process to kill.  We don't trust that initialPid
4463            // still has any relation to current pids, so must scan through the
4464            // list.
4465            synchronized (mPidsSelfLocked) {
4466                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4467                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4468                    if (p.uid != uid) {
4469                        continue;
4470                    }
4471                    if (p.pid == initialPid) {
4472                        proc = p;
4473                        break;
4474                    }
4475                    if (p.pkgList.containsKey(packageName)) {
4476                        proc = p;
4477                    }
4478                }
4479            }
4480
4481            if (proc == null) {
4482                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4483                        + " initialPid=" + initialPid
4484                        + " packageName=" + packageName);
4485                return;
4486            }
4487
4488            if (proc.thread != null) {
4489                if (proc.pid == Process.myPid()) {
4490                    Log.w(TAG, "crashApplication: trying to crash self!");
4491                    return;
4492                }
4493                long ident = Binder.clearCallingIdentity();
4494                try {
4495                    proc.thread.scheduleCrash(message);
4496                } catch (RemoteException e) {
4497                }
4498                Binder.restoreCallingIdentity(ident);
4499            }
4500        }
4501    }
4502
4503    @Override
4504    public final void finishSubActivity(IBinder token, String resultWho,
4505            int requestCode) {
4506        synchronized(this) {
4507            final long origId = Binder.clearCallingIdentity();
4508            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4509            if (r != null) {
4510                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4511            }
4512            Binder.restoreCallingIdentity(origId);
4513        }
4514    }
4515
4516    @Override
4517    public boolean finishActivityAffinity(IBinder token) {
4518        synchronized(this) {
4519            final long origId = Binder.clearCallingIdentity();
4520            try {
4521                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4522
4523                ActivityRecord rootR = r.task.getRootActivity();
4524                // Do not allow task to finish in Lock Task mode.
4525                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4526                    if (rootR == r) {
4527                        mStackSupervisor.showLockTaskToast();
4528                        return false;
4529                    }
4530                }
4531                boolean res = false;
4532                if (r != null) {
4533                    res = r.task.stack.finishActivityAffinityLocked(r);
4534                }
4535                return res;
4536            } finally {
4537                Binder.restoreCallingIdentity(origId);
4538            }
4539        }
4540    }
4541
4542    @Override
4543    public void finishVoiceTask(IVoiceInteractionSession session) {
4544        synchronized(this) {
4545            final long origId = Binder.clearCallingIdentity();
4546            try {
4547                mStackSupervisor.finishVoiceTask(session);
4548            } finally {
4549                Binder.restoreCallingIdentity(origId);
4550            }
4551        }
4552
4553    }
4554
4555    @Override
4556    public boolean releaseActivityInstance(IBinder token) {
4557        synchronized(this) {
4558            final long origId = Binder.clearCallingIdentity();
4559            try {
4560                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4561                if (r.task == null || r.task.stack == null) {
4562                    return false;
4563                }
4564                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4565            } finally {
4566                Binder.restoreCallingIdentity(origId);
4567            }
4568        }
4569    }
4570
4571    @Override
4572    public void releaseSomeActivities(IApplicationThread appInt) {
4573        synchronized(this) {
4574            final long origId = Binder.clearCallingIdentity();
4575            try {
4576                ProcessRecord app = getRecordForAppLocked(appInt);
4577                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4578            } finally {
4579                Binder.restoreCallingIdentity(origId);
4580            }
4581        }
4582    }
4583
4584    @Override
4585    public boolean willActivityBeVisible(IBinder token) {
4586        synchronized(this) {
4587            ActivityStack stack = ActivityRecord.getStackLocked(token);
4588            if (stack != null) {
4589                return stack.willActivityBeVisibleLocked(token);
4590            }
4591            return false;
4592        }
4593    }
4594
4595    @Override
4596    public void overridePendingTransition(IBinder token, String packageName,
4597            int enterAnim, int exitAnim) {
4598        synchronized(this) {
4599            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4600            if (self == null) {
4601                return;
4602            }
4603
4604            final long origId = Binder.clearCallingIdentity();
4605
4606            if (self.state == ActivityState.RESUMED
4607                    || self.state == ActivityState.PAUSING) {
4608                mWindowManager.overridePendingAppTransition(packageName,
4609                        enterAnim, exitAnim, null);
4610            }
4611
4612            Binder.restoreCallingIdentity(origId);
4613        }
4614    }
4615
4616    /**
4617     * Main function for removing an existing process from the activity manager
4618     * as a result of that process going away.  Clears out all connections
4619     * to the process.
4620     */
4621    private final void handleAppDiedLocked(ProcessRecord app,
4622            boolean restarting, boolean allowRestart) {
4623        int pid = app.pid;
4624        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4625        if (!restarting) {
4626            removeLruProcessLocked(app);
4627            if (pid > 0) {
4628                ProcessList.remove(pid);
4629            }
4630        }
4631
4632        if (mProfileProc == app) {
4633            clearProfilerLocked();
4634        }
4635
4636        // Remove this application's activities from active lists.
4637        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4638
4639        app.activities.clear();
4640
4641        if (app.instrumentationClass != null) {
4642            Slog.w(TAG, "Crash of app " + app.processName
4643                  + " running instrumentation " + app.instrumentationClass);
4644            Bundle info = new Bundle();
4645            info.putString("shortMsg", "Process crashed.");
4646            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4647        }
4648
4649        if (!restarting) {
4650            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4651                // If there was nothing to resume, and we are not already
4652                // restarting this process, but there is a visible activity that
4653                // is hosted by the process...  then make sure all visible
4654                // activities are running, taking care of restarting this
4655                // process.
4656                if (hasVisibleActivities) {
4657                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4658                }
4659            }
4660        }
4661    }
4662
4663    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4664        IBinder threadBinder = thread.asBinder();
4665        // Find the application record.
4666        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4667            ProcessRecord rec = mLruProcesses.get(i);
4668            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4669                return i;
4670            }
4671        }
4672        return -1;
4673    }
4674
4675    final ProcessRecord getRecordForAppLocked(
4676            IApplicationThread thread) {
4677        if (thread == null) {
4678            return null;
4679        }
4680
4681        int appIndex = getLRURecordIndexForAppLocked(thread);
4682        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4683    }
4684
4685    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4686        // If there are no longer any background processes running,
4687        // and the app that died was not running instrumentation,
4688        // then tell everyone we are now low on memory.
4689        boolean haveBg = false;
4690        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4691            ProcessRecord rec = mLruProcesses.get(i);
4692            if (rec.thread != null
4693                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4694                haveBg = true;
4695                break;
4696            }
4697        }
4698
4699        if (!haveBg) {
4700            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4701            if (doReport) {
4702                long now = SystemClock.uptimeMillis();
4703                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4704                    doReport = false;
4705                } else {
4706                    mLastMemUsageReportTime = now;
4707                }
4708            }
4709            final ArrayList<ProcessMemInfo> memInfos
4710                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4711            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4712            long now = SystemClock.uptimeMillis();
4713            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4714                ProcessRecord rec = mLruProcesses.get(i);
4715                if (rec == dyingProc || rec.thread == null) {
4716                    continue;
4717                }
4718                if (doReport) {
4719                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4720                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4721                }
4722                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4723                    // The low memory report is overriding any current
4724                    // state for a GC request.  Make sure to do
4725                    // heavy/important/visible/foreground processes first.
4726                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4727                        rec.lastRequestedGc = 0;
4728                    } else {
4729                        rec.lastRequestedGc = rec.lastLowMemory;
4730                    }
4731                    rec.reportLowMemory = true;
4732                    rec.lastLowMemory = now;
4733                    mProcessesToGc.remove(rec);
4734                    addProcessToGcListLocked(rec);
4735                }
4736            }
4737            if (doReport) {
4738                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4739                mHandler.sendMessage(msg);
4740            }
4741            scheduleAppGcsLocked();
4742        }
4743    }
4744
4745    final void appDiedLocked(ProcessRecord app) {
4746       appDiedLocked(app, app.pid, app.thread);
4747    }
4748
4749    final void appDiedLocked(ProcessRecord app, int pid,
4750            IApplicationThread thread) {
4751
4752        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4753        synchronized (stats) {
4754            stats.noteProcessDiedLocked(app.info.uid, pid);
4755        }
4756
4757        Process.killProcessGroup(app.info.uid, pid);
4758
4759        // Clean up already done if the process has been re-started.
4760        if (app.pid == pid && app.thread != null &&
4761                app.thread.asBinder() == thread.asBinder()) {
4762            boolean doLowMem = app.instrumentationClass == null;
4763            boolean doOomAdj = doLowMem;
4764            if (!app.killedByAm) {
4765                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4766                        + ") has died.");
4767                mAllowLowerMemLevel = true;
4768            } else {
4769                // Note that we always want to do oom adj to update our state with the
4770                // new number of procs.
4771                mAllowLowerMemLevel = false;
4772                doLowMem = false;
4773            }
4774            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4775            if (DEBUG_CLEANUP) Slog.v(
4776                TAG, "Dying app: " + app + ", pid: " + pid
4777                + ", thread: " + thread.asBinder());
4778            handleAppDiedLocked(app, false, true);
4779
4780            if (doOomAdj) {
4781                updateOomAdjLocked();
4782            }
4783            if (doLowMem) {
4784                doLowMemReportIfNeededLocked(app);
4785            }
4786        } else if (app.pid != pid) {
4787            // A new process has already been started.
4788            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4789                    + ") has died and restarted (pid " + app.pid + ").");
4790            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4791        } else if (DEBUG_PROCESSES) {
4792            Slog.d(TAG, "Received spurious death notification for thread "
4793                    + thread.asBinder());
4794        }
4795    }
4796
4797    /**
4798     * If a stack trace dump file is configured, dump process stack traces.
4799     * @param clearTraces causes the dump file to be erased prior to the new
4800     *    traces being written, if true; when false, the new traces will be
4801     *    appended to any existing file content.
4802     * @param firstPids of dalvik VM processes to dump stack traces for first
4803     * @param lastPids of dalvik VM processes to dump stack traces for last
4804     * @param nativeProcs optional list of native process names to dump stack crawls
4805     * @return file containing stack traces, or null if no dump file is configured
4806     */
4807    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4808            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4809        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4810        if (tracesPath == null || tracesPath.length() == 0) {
4811            return null;
4812        }
4813
4814        File tracesFile = new File(tracesPath);
4815        try {
4816            File tracesDir = tracesFile.getParentFile();
4817            if (!tracesDir.exists()) {
4818                tracesFile.mkdirs();
4819                if (!SELinux.restorecon(tracesDir)) {
4820                    return null;
4821                }
4822            }
4823            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4824
4825            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4826            tracesFile.createNewFile();
4827            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4828        } catch (IOException e) {
4829            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4830            return null;
4831        }
4832
4833        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4834        return tracesFile;
4835    }
4836
4837    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4838            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4839        // Use a FileObserver to detect when traces finish writing.
4840        // The order of traces is considered important to maintain for legibility.
4841        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4842            @Override
4843            public synchronized void onEvent(int event, String path) { notify(); }
4844        };
4845
4846        try {
4847            observer.startWatching();
4848
4849            // First collect all of the stacks of the most important pids.
4850            if (firstPids != null) {
4851                try {
4852                    int num = firstPids.size();
4853                    for (int i = 0; i < num; i++) {
4854                        synchronized (observer) {
4855                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4856                            observer.wait(200);  // Wait for write-close, give up after 200msec
4857                        }
4858                    }
4859                } catch (InterruptedException e) {
4860                    Log.wtf(TAG, e);
4861                }
4862            }
4863
4864            // Next collect the stacks of the native pids
4865            if (nativeProcs != null) {
4866                int[] pids = Process.getPidsForCommands(nativeProcs);
4867                if (pids != null) {
4868                    for (int pid : pids) {
4869                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4870                    }
4871                }
4872            }
4873
4874            // Lastly, measure CPU usage.
4875            if (processCpuTracker != null) {
4876                processCpuTracker.init();
4877                System.gc();
4878                processCpuTracker.update();
4879                try {
4880                    synchronized (processCpuTracker) {
4881                        processCpuTracker.wait(500); // measure over 1/2 second.
4882                    }
4883                } catch (InterruptedException e) {
4884                }
4885                processCpuTracker.update();
4886
4887                // We'll take the stack crawls of just the top apps using CPU.
4888                final int N = processCpuTracker.countWorkingStats();
4889                int numProcs = 0;
4890                for (int i=0; i<N && numProcs<5; i++) {
4891                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4892                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4893                        numProcs++;
4894                        try {
4895                            synchronized (observer) {
4896                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4897                                observer.wait(200);  // Wait for write-close, give up after 200msec
4898                            }
4899                        } catch (InterruptedException e) {
4900                            Log.wtf(TAG, e);
4901                        }
4902
4903                    }
4904                }
4905            }
4906        } finally {
4907            observer.stopWatching();
4908        }
4909    }
4910
4911    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4912        if (true || IS_USER_BUILD) {
4913            return;
4914        }
4915        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4916        if (tracesPath == null || tracesPath.length() == 0) {
4917            return;
4918        }
4919
4920        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4921        StrictMode.allowThreadDiskWrites();
4922        try {
4923            final File tracesFile = new File(tracesPath);
4924            final File tracesDir = tracesFile.getParentFile();
4925            final File tracesTmp = new File(tracesDir, "__tmp__");
4926            try {
4927                if (!tracesDir.exists()) {
4928                    tracesFile.mkdirs();
4929                    if (!SELinux.restorecon(tracesDir.getPath())) {
4930                        return;
4931                    }
4932                }
4933                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4934
4935                if (tracesFile.exists()) {
4936                    tracesTmp.delete();
4937                    tracesFile.renameTo(tracesTmp);
4938                }
4939                StringBuilder sb = new StringBuilder();
4940                Time tobj = new Time();
4941                tobj.set(System.currentTimeMillis());
4942                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4943                sb.append(": ");
4944                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4945                sb.append(" since ");
4946                sb.append(msg);
4947                FileOutputStream fos = new FileOutputStream(tracesFile);
4948                fos.write(sb.toString().getBytes());
4949                if (app == null) {
4950                    fos.write("\n*** No application process!".getBytes());
4951                }
4952                fos.close();
4953                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4954            } catch (IOException e) {
4955                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4956                return;
4957            }
4958
4959            if (app != null) {
4960                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4961                firstPids.add(app.pid);
4962                dumpStackTraces(tracesPath, firstPids, null, null, null);
4963            }
4964
4965            File lastTracesFile = null;
4966            File curTracesFile = null;
4967            for (int i=9; i>=0; i--) {
4968                String name = String.format(Locale.US, "slow%02d.txt", i);
4969                curTracesFile = new File(tracesDir, name);
4970                if (curTracesFile.exists()) {
4971                    if (lastTracesFile != null) {
4972                        curTracesFile.renameTo(lastTracesFile);
4973                    } else {
4974                        curTracesFile.delete();
4975                    }
4976                }
4977                lastTracesFile = curTracesFile;
4978            }
4979            tracesFile.renameTo(curTracesFile);
4980            if (tracesTmp.exists()) {
4981                tracesTmp.renameTo(tracesFile);
4982            }
4983        } finally {
4984            StrictMode.setThreadPolicy(oldPolicy);
4985        }
4986    }
4987
4988    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4989            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4990        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4991        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4992
4993        if (mController != null) {
4994            try {
4995                // 0 == continue, -1 = kill process immediately
4996                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4997                if (res < 0 && app.pid != MY_PID) {
4998                    app.kill("anr", true);
4999                }
5000            } catch (RemoteException e) {
5001                mController = null;
5002                Watchdog.getInstance().setActivityController(null);
5003            }
5004        }
5005
5006        long anrTime = SystemClock.uptimeMillis();
5007        if (MONITOR_CPU_USAGE) {
5008            updateCpuStatsNow();
5009        }
5010
5011        synchronized (this) {
5012            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
5013            if (mShuttingDown) {
5014                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
5015                return;
5016            } else if (app.notResponding) {
5017                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
5018                return;
5019            } else if (app.crashing) {
5020                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5021                return;
5022            }
5023
5024            // In case we come through here for the same app before completing
5025            // this one, mark as anring now so we will bail out.
5026            app.notResponding = true;
5027
5028            // Log the ANR to the event log.
5029            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5030                    app.processName, app.info.flags, annotation);
5031
5032            // Dump thread traces as quickly as we can, starting with "interesting" processes.
5033            firstPids.add(app.pid);
5034
5035            int parentPid = app.pid;
5036            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5037            if (parentPid != app.pid) firstPids.add(parentPid);
5038
5039            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5040
5041            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5042                ProcessRecord r = mLruProcesses.get(i);
5043                if (r != null && r.thread != null) {
5044                    int pid = r.pid;
5045                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5046                        if (r.persistent) {
5047                            firstPids.add(pid);
5048                        } else {
5049                            lastPids.put(pid, Boolean.TRUE);
5050                        }
5051                    }
5052                }
5053            }
5054        }
5055
5056        // Log the ANR to the main log.
5057        StringBuilder info = new StringBuilder();
5058        info.setLength(0);
5059        info.append("ANR in ").append(app.processName);
5060        if (activity != null && activity.shortComponentName != null) {
5061            info.append(" (").append(activity.shortComponentName).append(")");
5062        }
5063        info.append("\n");
5064        info.append("PID: ").append(app.pid).append("\n");
5065        if (annotation != null) {
5066            info.append("Reason: ").append(annotation).append("\n");
5067        }
5068        if (parent != null && parent != activity) {
5069            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5070        }
5071
5072        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5073
5074        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5075                NATIVE_STACKS_OF_INTEREST);
5076
5077        String cpuInfo = null;
5078        if (MONITOR_CPU_USAGE) {
5079            updateCpuStatsNow();
5080            synchronized (mProcessCpuTracker) {
5081                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5082            }
5083            info.append(processCpuTracker.printCurrentLoad());
5084            info.append(cpuInfo);
5085        }
5086
5087        info.append(processCpuTracker.printCurrentState(anrTime));
5088
5089        Slog.e(TAG, info.toString());
5090        if (tracesFile == null) {
5091            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5092            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5093        }
5094
5095        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5096                cpuInfo, tracesFile, null);
5097
5098        if (mController != null) {
5099            try {
5100                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5101                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5102                if (res != 0) {
5103                    if (res < 0 && app.pid != MY_PID) {
5104                        app.kill("anr", true);
5105                    } else {
5106                        synchronized (this) {
5107                            mServices.scheduleServiceTimeoutLocked(app);
5108                        }
5109                    }
5110                    return;
5111                }
5112            } catch (RemoteException e) {
5113                mController = null;
5114                Watchdog.getInstance().setActivityController(null);
5115            }
5116        }
5117
5118        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5119        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5120                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5121
5122        synchronized (this) {
5123            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5124                app.kill("bg anr", true);
5125                return;
5126            }
5127
5128            // Set the app's notResponding state, and look up the errorReportReceiver
5129            makeAppNotRespondingLocked(app,
5130                    activity != null ? activity.shortComponentName : null,
5131                    annotation != null ? "ANR " + annotation : "ANR",
5132                    info.toString());
5133
5134            // Bring up the infamous App Not Responding dialog
5135            Message msg = Message.obtain();
5136            HashMap<String, Object> map = new HashMap<String, Object>();
5137            msg.what = SHOW_NOT_RESPONDING_MSG;
5138            msg.obj = map;
5139            msg.arg1 = aboveSystem ? 1 : 0;
5140            map.put("app", app);
5141            if (activity != null) {
5142                map.put("activity", activity);
5143            }
5144
5145            mHandler.sendMessage(msg);
5146        }
5147    }
5148
5149    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5150        if (!mLaunchWarningShown) {
5151            mLaunchWarningShown = true;
5152            mHandler.post(new Runnable() {
5153                @Override
5154                public void run() {
5155                    synchronized (ActivityManagerService.this) {
5156                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5157                        d.show();
5158                        mHandler.postDelayed(new Runnable() {
5159                            @Override
5160                            public void run() {
5161                                synchronized (ActivityManagerService.this) {
5162                                    d.dismiss();
5163                                    mLaunchWarningShown = false;
5164                                }
5165                            }
5166                        }, 4000);
5167                    }
5168                }
5169            });
5170        }
5171    }
5172
5173    @Override
5174    public boolean clearApplicationUserData(final String packageName,
5175            final IPackageDataObserver observer, int userId) {
5176        enforceNotIsolatedCaller("clearApplicationUserData");
5177        int uid = Binder.getCallingUid();
5178        int pid = Binder.getCallingPid();
5179        userId = handleIncomingUser(pid, uid,
5180                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5181        long callingId = Binder.clearCallingIdentity();
5182        try {
5183            IPackageManager pm = AppGlobals.getPackageManager();
5184            int pkgUid = -1;
5185            synchronized(this) {
5186                try {
5187                    pkgUid = pm.getPackageUid(packageName, userId);
5188                } catch (RemoteException e) {
5189                }
5190                if (pkgUid == -1) {
5191                    Slog.w(TAG, "Invalid packageName: " + packageName);
5192                    if (observer != null) {
5193                        try {
5194                            observer.onRemoveCompleted(packageName, false);
5195                        } catch (RemoteException e) {
5196                            Slog.i(TAG, "Observer no longer exists.");
5197                        }
5198                    }
5199                    return false;
5200                }
5201                if (uid == pkgUid || checkComponentPermission(
5202                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5203                        pid, uid, -1, true)
5204                        == PackageManager.PERMISSION_GRANTED) {
5205                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5206                } else {
5207                    throw new SecurityException("PID " + pid + " does not have permission "
5208                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5209                                    + " of package " + packageName);
5210                }
5211
5212                // Remove all tasks match the cleared application package and user
5213                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5214                    final TaskRecord tr = mRecentTasks.get(i);
5215                    final String taskPackageName =
5216                            tr.getBaseIntent().getComponent().getPackageName();
5217                    if (tr.userId != userId) continue;
5218                    if (!taskPackageName.equals(packageName)) continue;
5219                    removeTaskByIdLocked(tr.taskId, 0);
5220                }
5221            }
5222
5223            try {
5224                // Clear application user data
5225                pm.clearApplicationUserData(packageName, observer, userId);
5226
5227                synchronized(this) {
5228                    // Remove all permissions granted from/to this package
5229                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5230                }
5231
5232                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5233                        Uri.fromParts("package", packageName, null));
5234                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5235                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5236                        null, null, 0, null, null, null, false, false, userId);
5237            } catch (RemoteException e) {
5238            }
5239        } finally {
5240            Binder.restoreCallingIdentity(callingId);
5241        }
5242        return true;
5243    }
5244
5245    @Override
5246    public void killBackgroundProcesses(final String packageName, int userId) {
5247        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5248                != PackageManager.PERMISSION_GRANTED &&
5249                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5250                        != PackageManager.PERMISSION_GRANTED) {
5251            String msg = "Permission Denial: killBackgroundProcesses() 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        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5260                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5261        long callingId = Binder.clearCallingIdentity();
5262        try {
5263            IPackageManager pm = AppGlobals.getPackageManager();
5264            synchronized(this) {
5265                int appId = -1;
5266                try {
5267                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5268                } catch (RemoteException e) {
5269                }
5270                if (appId == -1) {
5271                    Slog.w(TAG, "Invalid packageName: " + packageName);
5272                    return;
5273                }
5274                killPackageProcessesLocked(packageName, appId, userId,
5275                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5276            }
5277        } finally {
5278            Binder.restoreCallingIdentity(callingId);
5279        }
5280    }
5281
5282    @Override
5283    public void killAllBackgroundProcesses() {
5284        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5285                != PackageManager.PERMISSION_GRANTED) {
5286            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5287                    + Binder.getCallingPid()
5288                    + ", uid=" + Binder.getCallingUid()
5289                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5290            Slog.w(TAG, msg);
5291            throw new SecurityException(msg);
5292        }
5293
5294        long callingId = Binder.clearCallingIdentity();
5295        try {
5296            synchronized(this) {
5297                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5298                final int NP = mProcessNames.getMap().size();
5299                for (int ip=0; ip<NP; ip++) {
5300                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5301                    final int NA = apps.size();
5302                    for (int ia=0; ia<NA; ia++) {
5303                        ProcessRecord app = apps.valueAt(ia);
5304                        if (app.persistent) {
5305                            // we don't kill persistent processes
5306                            continue;
5307                        }
5308                        if (app.removed) {
5309                            procs.add(app);
5310                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5311                            app.removed = true;
5312                            procs.add(app);
5313                        }
5314                    }
5315                }
5316
5317                int N = procs.size();
5318                for (int i=0; i<N; i++) {
5319                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5320                }
5321                mAllowLowerMemLevel = true;
5322                updateOomAdjLocked();
5323                doLowMemReportIfNeededLocked(null);
5324            }
5325        } finally {
5326            Binder.restoreCallingIdentity(callingId);
5327        }
5328    }
5329
5330    @Override
5331    public void forceStopPackage(final String packageName, int userId) {
5332        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5333                != PackageManager.PERMISSION_GRANTED) {
5334            String msg = "Permission Denial: forceStopPackage() from pid="
5335                    + Binder.getCallingPid()
5336                    + ", uid=" + Binder.getCallingUid()
5337                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5338            Slog.w(TAG, msg);
5339            throw new SecurityException(msg);
5340        }
5341        final int callingPid = Binder.getCallingPid();
5342        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5343                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5344        long callingId = Binder.clearCallingIdentity();
5345        try {
5346            IPackageManager pm = AppGlobals.getPackageManager();
5347            synchronized(this) {
5348                int[] users = userId == UserHandle.USER_ALL
5349                        ? getUsersLocked() : new int[] { userId };
5350                for (int user : users) {
5351                    int pkgUid = -1;
5352                    try {
5353                        pkgUid = pm.getPackageUid(packageName, user);
5354                    } catch (RemoteException e) {
5355                    }
5356                    if (pkgUid == -1) {
5357                        Slog.w(TAG, "Invalid packageName: " + packageName);
5358                        continue;
5359                    }
5360                    try {
5361                        pm.setPackageStoppedState(packageName, true, user);
5362                    } catch (RemoteException e) {
5363                    } catch (IllegalArgumentException e) {
5364                        Slog.w(TAG, "Failed trying to unstop package "
5365                                + packageName + ": " + e);
5366                    }
5367                    if (isUserRunningLocked(user, false)) {
5368                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5369                    }
5370                }
5371            }
5372        } finally {
5373            Binder.restoreCallingIdentity(callingId);
5374        }
5375    }
5376
5377    @Override
5378    public void addPackageDependency(String packageName) {
5379        synchronized (this) {
5380            int callingPid = Binder.getCallingPid();
5381            if (callingPid == Process.myPid()) {
5382                //  Yeah, um, no.
5383                Slog.w(TAG, "Can't addPackageDependency on system process");
5384                return;
5385            }
5386            ProcessRecord proc;
5387            synchronized (mPidsSelfLocked) {
5388                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5389            }
5390            if (proc != null) {
5391                if (proc.pkgDeps == null) {
5392                    proc.pkgDeps = new ArraySet<String>(1);
5393                }
5394                proc.pkgDeps.add(packageName);
5395            }
5396        }
5397    }
5398
5399    /*
5400     * The pkg name and app id have to be specified.
5401     */
5402    @Override
5403    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5404        if (pkg == null) {
5405            return;
5406        }
5407        // Make sure the uid is valid.
5408        if (appid < 0) {
5409            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5410            return;
5411        }
5412        int callerUid = Binder.getCallingUid();
5413        // Only the system server can kill an application
5414        if (callerUid == Process.SYSTEM_UID) {
5415            // Post an aysnc message to kill the application
5416            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5417            msg.arg1 = appid;
5418            msg.arg2 = 0;
5419            Bundle bundle = new Bundle();
5420            bundle.putString("pkg", pkg);
5421            bundle.putString("reason", reason);
5422            msg.obj = bundle;
5423            mHandler.sendMessage(msg);
5424        } else {
5425            throw new SecurityException(callerUid + " cannot kill pkg: " +
5426                    pkg);
5427        }
5428    }
5429
5430    @Override
5431    public void closeSystemDialogs(String reason) {
5432        enforceNotIsolatedCaller("closeSystemDialogs");
5433
5434        final int pid = Binder.getCallingPid();
5435        final int uid = Binder.getCallingUid();
5436        final long origId = Binder.clearCallingIdentity();
5437        try {
5438            synchronized (this) {
5439                // Only allow this from foreground processes, so that background
5440                // applications can't abuse it to prevent system UI from being shown.
5441                if (uid >= Process.FIRST_APPLICATION_UID) {
5442                    ProcessRecord proc;
5443                    synchronized (mPidsSelfLocked) {
5444                        proc = mPidsSelfLocked.get(pid);
5445                    }
5446                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5447                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5448                                + " from background process " + proc);
5449                        return;
5450                    }
5451                }
5452                closeSystemDialogsLocked(reason);
5453            }
5454        } finally {
5455            Binder.restoreCallingIdentity(origId);
5456        }
5457    }
5458
5459    void closeSystemDialogsLocked(String reason) {
5460        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5461        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5462                | Intent.FLAG_RECEIVER_FOREGROUND);
5463        if (reason != null) {
5464            intent.putExtra("reason", reason);
5465        }
5466        mWindowManager.closeSystemDialogs(reason);
5467
5468        mStackSupervisor.closeSystemDialogsLocked();
5469
5470        broadcastIntentLocked(null, null, intent, null,
5471                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5472                Process.SYSTEM_UID, UserHandle.USER_ALL);
5473    }
5474
5475    @Override
5476    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5477        enforceNotIsolatedCaller("getProcessMemoryInfo");
5478        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5479        for (int i=pids.length-1; i>=0; i--) {
5480            ProcessRecord proc;
5481            int oomAdj;
5482            synchronized (this) {
5483                synchronized (mPidsSelfLocked) {
5484                    proc = mPidsSelfLocked.get(pids[i]);
5485                    oomAdj = proc != null ? proc.setAdj : 0;
5486                }
5487            }
5488            infos[i] = new Debug.MemoryInfo();
5489            Debug.getMemoryInfo(pids[i], infos[i]);
5490            if (proc != null) {
5491                synchronized (this) {
5492                    if (proc.thread != null && proc.setAdj == oomAdj) {
5493                        // Record this for posterity if the process has been stable.
5494                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5495                                infos[i].getTotalUss(), false, proc.pkgList);
5496                    }
5497                }
5498            }
5499        }
5500        return infos;
5501    }
5502
5503    @Override
5504    public long[] getProcessPss(int[] pids) {
5505        enforceNotIsolatedCaller("getProcessPss");
5506        long[] pss = new long[pids.length];
5507        for (int i=pids.length-1; i>=0; i--) {
5508            ProcessRecord proc;
5509            int oomAdj;
5510            synchronized (this) {
5511                synchronized (mPidsSelfLocked) {
5512                    proc = mPidsSelfLocked.get(pids[i]);
5513                    oomAdj = proc != null ? proc.setAdj : 0;
5514                }
5515            }
5516            long[] tmpUss = new long[1];
5517            pss[i] = Debug.getPss(pids[i], tmpUss);
5518            if (proc != null) {
5519                synchronized (this) {
5520                    if (proc.thread != null && proc.setAdj == oomAdj) {
5521                        // Record this for posterity if the process has been stable.
5522                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5523                    }
5524                }
5525            }
5526        }
5527        return pss;
5528    }
5529
5530    @Override
5531    public void killApplicationProcess(String processName, int uid) {
5532        if (processName == null) {
5533            return;
5534        }
5535
5536        int callerUid = Binder.getCallingUid();
5537        // Only the system server can kill an application
5538        if (callerUid == Process.SYSTEM_UID) {
5539            synchronized (this) {
5540                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5541                if (app != null && app.thread != null) {
5542                    try {
5543                        app.thread.scheduleSuicide();
5544                    } catch (RemoteException e) {
5545                        // If the other end already died, then our work here is done.
5546                    }
5547                } else {
5548                    Slog.w(TAG, "Process/uid not found attempting kill of "
5549                            + processName + " / " + uid);
5550                }
5551            }
5552        } else {
5553            throw new SecurityException(callerUid + " cannot kill app process: " +
5554                    processName);
5555        }
5556    }
5557
5558    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5559        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5560                false, true, false, false, UserHandle.getUserId(uid), reason);
5561        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5562                Uri.fromParts("package", packageName, null));
5563        if (!mProcessesReady) {
5564            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5565                    | Intent.FLAG_RECEIVER_FOREGROUND);
5566        }
5567        intent.putExtra(Intent.EXTRA_UID, uid);
5568        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5569        broadcastIntentLocked(null, null, intent,
5570                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5571                false, false,
5572                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5573    }
5574
5575    private void forceStopUserLocked(int userId, String reason) {
5576        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5577        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5578        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5579                | Intent.FLAG_RECEIVER_FOREGROUND);
5580        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5581        broadcastIntentLocked(null, null, intent,
5582                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5583                false, false,
5584                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5585    }
5586
5587    private final boolean killPackageProcessesLocked(String packageName, int appId,
5588            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5589            boolean doit, boolean evenPersistent, String reason) {
5590        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5591
5592        // Remove all processes this package may have touched: all with the
5593        // same UID (except for the system or root user), and all whose name
5594        // matches the package name.
5595        final int NP = mProcessNames.getMap().size();
5596        for (int ip=0; ip<NP; ip++) {
5597            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5598            final int NA = apps.size();
5599            for (int ia=0; ia<NA; ia++) {
5600                ProcessRecord app = apps.valueAt(ia);
5601                if (app.persistent && !evenPersistent) {
5602                    // we don't kill persistent processes
5603                    continue;
5604                }
5605                if (app.removed) {
5606                    if (doit) {
5607                        procs.add(app);
5608                    }
5609                    continue;
5610                }
5611
5612                // Skip process if it doesn't meet our oom adj requirement.
5613                if (app.setAdj < minOomAdj) {
5614                    continue;
5615                }
5616
5617                // If no package is specified, we call all processes under the
5618                // give user id.
5619                if (packageName == null) {
5620                    if (app.userId != userId) {
5621                        continue;
5622                    }
5623                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5624                        continue;
5625                    }
5626                // Package has been specified, we want to hit all processes
5627                // that match it.  We need to qualify this by the processes
5628                // that are running under the specified app and user ID.
5629                } else {
5630                    final boolean isDep = app.pkgDeps != null
5631                            && app.pkgDeps.contains(packageName);
5632                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5633                        continue;
5634                    }
5635                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5636                        continue;
5637                    }
5638                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5639                        continue;
5640                    }
5641                }
5642
5643                // Process has passed all conditions, kill it!
5644                if (!doit) {
5645                    return true;
5646                }
5647                app.removed = true;
5648                procs.add(app);
5649            }
5650        }
5651
5652        int N = procs.size();
5653        for (int i=0; i<N; i++) {
5654            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5655        }
5656        updateOomAdjLocked();
5657        return N > 0;
5658    }
5659
5660    private final boolean forceStopPackageLocked(String name, int appId,
5661            boolean callerWillRestart, boolean purgeCache, boolean doit,
5662            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5663        int i;
5664        int N;
5665
5666        if (userId == UserHandle.USER_ALL && name == null) {
5667            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5668        }
5669
5670        if (appId < 0 && name != null) {
5671            try {
5672                appId = UserHandle.getAppId(
5673                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5674            } catch (RemoteException e) {
5675            }
5676        }
5677
5678        if (doit) {
5679            if (name != null) {
5680                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5681                        + " user=" + userId + ": " + reason);
5682            } else {
5683                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5684            }
5685
5686            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5687            for (int ip=pmap.size()-1; ip>=0; ip--) {
5688                SparseArray<Long> ba = pmap.valueAt(ip);
5689                for (i=ba.size()-1; i>=0; i--) {
5690                    boolean remove = false;
5691                    final int entUid = ba.keyAt(i);
5692                    if (name != null) {
5693                        if (userId == UserHandle.USER_ALL) {
5694                            if (UserHandle.getAppId(entUid) == appId) {
5695                                remove = true;
5696                            }
5697                        } else {
5698                            if (entUid == UserHandle.getUid(userId, appId)) {
5699                                remove = true;
5700                            }
5701                        }
5702                    } else if (UserHandle.getUserId(entUid) == userId) {
5703                        remove = true;
5704                    }
5705                    if (remove) {
5706                        ba.removeAt(i);
5707                    }
5708                }
5709                if (ba.size() == 0) {
5710                    pmap.removeAt(ip);
5711                }
5712            }
5713        }
5714
5715        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5716                -100, callerWillRestart, true, doit, evenPersistent,
5717                name == null ? ("stop user " + userId) : ("stop " + name));
5718
5719        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5720            if (!doit) {
5721                return true;
5722            }
5723            didSomething = true;
5724        }
5725
5726        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5727            if (!doit) {
5728                return true;
5729            }
5730            didSomething = true;
5731        }
5732
5733        if (name == null) {
5734            // Remove all sticky broadcasts from this user.
5735            mStickyBroadcasts.remove(userId);
5736        }
5737
5738        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5739        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5740                userId, providers)) {
5741            if (!doit) {
5742                return true;
5743            }
5744            didSomething = true;
5745        }
5746        N = providers.size();
5747        for (i=0; i<N; i++) {
5748            removeDyingProviderLocked(null, providers.get(i), true);
5749        }
5750
5751        // Remove transient permissions granted from/to this package/user
5752        removeUriPermissionsForPackageLocked(name, userId, false);
5753
5754        if (name == null || uninstalling) {
5755            // Remove pending intents.  For now we only do this when force
5756            // stopping users, because we have some problems when doing this
5757            // for packages -- app widgets are not currently cleaned up for
5758            // such packages, so they can be left with bad pending intents.
5759            if (mIntentSenderRecords.size() > 0) {
5760                Iterator<WeakReference<PendingIntentRecord>> it
5761                        = mIntentSenderRecords.values().iterator();
5762                while (it.hasNext()) {
5763                    WeakReference<PendingIntentRecord> wpir = it.next();
5764                    if (wpir == null) {
5765                        it.remove();
5766                        continue;
5767                    }
5768                    PendingIntentRecord pir = wpir.get();
5769                    if (pir == null) {
5770                        it.remove();
5771                        continue;
5772                    }
5773                    if (name == null) {
5774                        // Stopping user, remove all objects for the user.
5775                        if (pir.key.userId != userId) {
5776                            // Not the same user, skip it.
5777                            continue;
5778                        }
5779                    } else {
5780                        if (UserHandle.getAppId(pir.uid) != appId) {
5781                            // Different app id, skip it.
5782                            continue;
5783                        }
5784                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5785                            // Different user, skip it.
5786                            continue;
5787                        }
5788                        if (!pir.key.packageName.equals(name)) {
5789                            // Different package, skip it.
5790                            continue;
5791                        }
5792                    }
5793                    if (!doit) {
5794                        return true;
5795                    }
5796                    didSomething = true;
5797                    it.remove();
5798                    pir.canceled = true;
5799                    if (pir.key.activity != null) {
5800                        pir.key.activity.pendingResults.remove(pir.ref);
5801                    }
5802                }
5803            }
5804        }
5805
5806        if (doit) {
5807            if (purgeCache && name != null) {
5808                AttributeCache ac = AttributeCache.instance();
5809                if (ac != null) {
5810                    ac.removePackage(name);
5811                }
5812            }
5813            if (mBooted) {
5814                mStackSupervisor.resumeTopActivitiesLocked();
5815                mStackSupervisor.scheduleIdleLocked();
5816            }
5817        }
5818
5819        return didSomething;
5820    }
5821
5822    private final boolean removeProcessLocked(ProcessRecord app,
5823            boolean callerWillRestart, boolean allowRestart, String reason) {
5824        final String name = app.processName;
5825        final int uid = app.uid;
5826        if (DEBUG_PROCESSES) Slog.d(
5827            TAG, "Force removing proc " + app.toShortString() + " (" + name
5828            + "/" + uid + ")");
5829
5830        mProcessNames.remove(name, uid);
5831        mIsolatedProcesses.remove(app.uid);
5832        if (mHeavyWeightProcess == app) {
5833            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5834                    mHeavyWeightProcess.userId, 0));
5835            mHeavyWeightProcess = null;
5836        }
5837        boolean needRestart = false;
5838        if (app.pid > 0 && app.pid != MY_PID) {
5839            int pid = app.pid;
5840            synchronized (mPidsSelfLocked) {
5841                mPidsSelfLocked.remove(pid);
5842                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5843            }
5844            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5845            if (app.isolated) {
5846                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5847            }
5848            app.kill(reason, true);
5849            handleAppDiedLocked(app, true, allowRestart);
5850            removeLruProcessLocked(app);
5851
5852            if (app.persistent && !app.isolated) {
5853                if (!callerWillRestart) {
5854                    addAppLocked(app.info, false, null /* ABI override */);
5855                } else {
5856                    needRestart = true;
5857                }
5858            }
5859        } else {
5860            mRemovedProcesses.add(app);
5861        }
5862
5863        return needRestart;
5864    }
5865
5866    private final void processStartTimedOutLocked(ProcessRecord app) {
5867        final int pid = app.pid;
5868        boolean gone = false;
5869        synchronized (mPidsSelfLocked) {
5870            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5871            if (knownApp != null && knownApp.thread == null) {
5872                mPidsSelfLocked.remove(pid);
5873                gone = true;
5874            }
5875        }
5876
5877        if (gone) {
5878            Slog.w(TAG, "Process " + app + " failed to attach");
5879            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5880                    pid, app.uid, app.processName);
5881            mProcessNames.remove(app.processName, app.uid);
5882            mIsolatedProcesses.remove(app.uid);
5883            if (mHeavyWeightProcess == app) {
5884                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5885                        mHeavyWeightProcess.userId, 0));
5886                mHeavyWeightProcess = null;
5887            }
5888            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5889            if (app.isolated) {
5890                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5891            }
5892            // Take care of any launching providers waiting for this process.
5893            checkAppInLaunchingProvidersLocked(app, true);
5894            // Take care of any services that are waiting for the process.
5895            mServices.processStartTimedOutLocked(app);
5896            app.kill("start timeout", true);
5897            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5898                Slog.w(TAG, "Unattached app died before backup, skipping");
5899                try {
5900                    IBackupManager bm = IBackupManager.Stub.asInterface(
5901                            ServiceManager.getService(Context.BACKUP_SERVICE));
5902                    bm.agentDisconnected(app.info.packageName);
5903                } catch (RemoteException e) {
5904                    // Can't happen; the backup manager is local
5905                }
5906            }
5907            if (isPendingBroadcastProcessLocked(pid)) {
5908                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5909                skipPendingBroadcastLocked(pid);
5910            }
5911        } else {
5912            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5913        }
5914    }
5915
5916    private final boolean attachApplicationLocked(IApplicationThread thread,
5917            int pid) {
5918
5919        // Find the application record that is being attached...  either via
5920        // the pid if we are running in multiple processes, or just pull the
5921        // next app record if we are emulating process with anonymous threads.
5922        ProcessRecord app;
5923        if (pid != MY_PID && pid >= 0) {
5924            synchronized (mPidsSelfLocked) {
5925                app = mPidsSelfLocked.get(pid);
5926            }
5927        } else {
5928            app = null;
5929        }
5930
5931        if (app == null) {
5932            Slog.w(TAG, "No pending application record for pid " + pid
5933                    + " (IApplicationThread " + thread + "); dropping process");
5934            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5935            if (pid > 0 && pid != MY_PID) {
5936                Process.killProcessQuiet(pid);
5937                //TODO: Process.killProcessGroup(app.info.uid, pid);
5938            } else {
5939                try {
5940                    thread.scheduleExit();
5941                } catch (Exception e) {
5942                    // Ignore exceptions.
5943                }
5944            }
5945            return false;
5946        }
5947
5948        // If this application record is still attached to a previous
5949        // process, clean it up now.
5950        if (app.thread != null) {
5951            handleAppDiedLocked(app, true, true);
5952        }
5953
5954        // Tell the process all about itself.
5955
5956        if (localLOGV) Slog.v(
5957                TAG, "Binding process pid " + pid + " to record " + app);
5958
5959        final String processName = app.processName;
5960        try {
5961            AppDeathRecipient adr = new AppDeathRecipient(
5962                    app, pid, thread);
5963            thread.asBinder().linkToDeath(adr, 0);
5964            app.deathRecipient = adr;
5965        } catch (RemoteException e) {
5966            app.resetPackageList(mProcessStats);
5967            startProcessLocked(app, "link fail", processName);
5968            return false;
5969        }
5970
5971        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5972
5973        app.makeActive(thread, mProcessStats);
5974        app.curAdj = app.setAdj = -100;
5975        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5976        app.forcingToForeground = null;
5977        updateProcessForegroundLocked(app, false, false);
5978        app.hasShownUi = false;
5979        app.debugging = false;
5980        app.cached = false;
5981
5982        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5983
5984        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5985        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5986
5987        if (!normalMode) {
5988            Slog.i(TAG, "Launching preboot mode app: " + app);
5989        }
5990
5991        if (localLOGV) Slog.v(
5992            TAG, "New app record " + app
5993            + " thread=" + thread.asBinder() + " pid=" + pid);
5994        try {
5995            int testMode = IApplicationThread.DEBUG_OFF;
5996            if (mDebugApp != null && mDebugApp.equals(processName)) {
5997                testMode = mWaitForDebugger
5998                    ? IApplicationThread.DEBUG_WAIT
5999                    : IApplicationThread.DEBUG_ON;
6000                app.debugging = true;
6001                if (mDebugTransient) {
6002                    mDebugApp = mOrigDebugApp;
6003                    mWaitForDebugger = mOrigWaitForDebugger;
6004                }
6005            }
6006            String profileFile = app.instrumentationProfileFile;
6007            ParcelFileDescriptor profileFd = null;
6008            int samplingInterval = 0;
6009            boolean profileAutoStop = false;
6010            if (mProfileApp != null && mProfileApp.equals(processName)) {
6011                mProfileProc = app;
6012                profileFile = mProfileFile;
6013                profileFd = mProfileFd;
6014                samplingInterval = mSamplingInterval;
6015                profileAutoStop = mAutoStopProfiler;
6016            }
6017            boolean enableOpenGlTrace = false;
6018            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6019                enableOpenGlTrace = true;
6020                mOpenGlTraceApp = null;
6021            }
6022
6023            // If the app is being launched for restore or full backup, set it up specially
6024            boolean isRestrictedBackupMode = false;
6025            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6026                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6027                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6028                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6029            }
6030
6031            ensurePackageDexOpt(app.instrumentationInfo != null
6032                    ? app.instrumentationInfo.packageName
6033                    : app.info.packageName);
6034            if (app.instrumentationClass != null) {
6035                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6036            }
6037            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
6038                    + processName + " with config " + mConfiguration);
6039            ApplicationInfo appInfo = app.instrumentationInfo != null
6040                    ? app.instrumentationInfo : app.info;
6041            app.compat = compatibilityInfoForPackageLocked(appInfo);
6042            if (profileFd != null) {
6043                profileFd = profileFd.dup();
6044            }
6045            ProfilerInfo profilerInfo = profileFile == null ? null
6046                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6047            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6048                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6049                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6050                    isRestrictedBackupMode || !normalMode, app.persistent,
6051                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
6052                    mCoreSettingsObserver.getCoreSettingsLocked());
6053            updateLruProcessLocked(app, false, null);
6054            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6055        } catch (Exception e) {
6056            // todo: Yikes!  What should we do?  For now we will try to
6057            // start another process, but that could easily get us in
6058            // an infinite loop of restarting processes...
6059            Slog.w(TAG, "Exception thrown during bind!", e);
6060
6061            app.resetPackageList(mProcessStats);
6062            app.unlinkDeathRecipient();
6063            startProcessLocked(app, "bind fail", processName);
6064            return false;
6065        }
6066
6067        // Remove this record from the list of starting applications.
6068        mPersistentStartingProcesses.remove(app);
6069        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6070                "Attach application locked removing on hold: " + app);
6071        mProcessesOnHold.remove(app);
6072
6073        boolean badApp = false;
6074        boolean didSomething = false;
6075
6076        // See if the top visible activity is waiting to run in this process...
6077        if (normalMode) {
6078            try {
6079                if (mStackSupervisor.attachApplicationLocked(app)) {
6080                    didSomething = true;
6081                }
6082            } catch (Exception e) {
6083                badApp = true;
6084            }
6085        }
6086
6087        // Find any services that should be running in this process...
6088        if (!badApp) {
6089            try {
6090                didSomething |= mServices.attachApplicationLocked(app, processName);
6091            } catch (Exception e) {
6092                badApp = true;
6093            }
6094        }
6095
6096        // Check if a next-broadcast receiver is in this process...
6097        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6098            try {
6099                didSomething |= sendPendingBroadcastsLocked(app);
6100            } catch (Exception e) {
6101                // If the app died trying to launch the receiver we declare it 'bad'
6102                badApp = true;
6103            }
6104        }
6105
6106        // Check whether the next backup agent is in this process...
6107        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6108            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6109            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6110            try {
6111                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6112                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6113                        mBackupTarget.backupMode);
6114            } catch (Exception e) {
6115                Slog.w(TAG, "Exception scheduling backup agent creation: ");
6116                e.printStackTrace();
6117            }
6118        }
6119
6120        if (badApp) {
6121            // todo: Also need to kill application to deal with all
6122            // kinds of exceptions.
6123            handleAppDiedLocked(app, false, true);
6124            return false;
6125        }
6126
6127        if (!didSomething) {
6128            updateOomAdjLocked();
6129        }
6130
6131        return true;
6132    }
6133
6134    @Override
6135    public final void attachApplication(IApplicationThread thread) {
6136        synchronized (this) {
6137            int callingPid = Binder.getCallingPid();
6138            final long origId = Binder.clearCallingIdentity();
6139            attachApplicationLocked(thread, callingPid);
6140            Binder.restoreCallingIdentity(origId);
6141        }
6142    }
6143
6144    @Override
6145    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6146        final long origId = Binder.clearCallingIdentity();
6147        synchronized (this) {
6148            ActivityStack stack = ActivityRecord.getStackLocked(token);
6149            if (stack != null) {
6150                ActivityRecord r =
6151                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6152                if (stopProfiling) {
6153                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6154                        try {
6155                            mProfileFd.close();
6156                        } catch (IOException e) {
6157                        }
6158                        clearProfilerLocked();
6159                    }
6160                }
6161            }
6162        }
6163        Binder.restoreCallingIdentity(origId);
6164    }
6165
6166    void postEnableScreenAfterBootLocked() {
6167        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
6168    }
6169
6170    void enableScreenAfterBoot() {
6171        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6172                SystemClock.uptimeMillis());
6173        mWindowManager.enableScreenAfterBoot();
6174
6175        synchronized (this) {
6176            updateEventDispatchingLocked();
6177        }
6178    }
6179
6180    @Override
6181    public void showBootMessage(final CharSequence msg, final boolean always) {
6182        enforceNotIsolatedCaller("showBootMessage");
6183        mWindowManager.showBootMessage(msg, always);
6184    }
6185
6186    @Override
6187    public void keyguardWaitingForActivityDrawn() {
6188        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6189        final long token = Binder.clearCallingIdentity();
6190        try {
6191            synchronized (this) {
6192                if (DEBUG_LOCKSCREEN) logLockScreen("");
6193                mWindowManager.keyguardWaitingForActivityDrawn();
6194            }
6195        } finally {
6196            Binder.restoreCallingIdentity(token);
6197        }
6198    }
6199
6200    final void finishBooting() {
6201        // Register receivers to handle package update events
6202        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
6203
6204        // Let system services know.
6205        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6206
6207        synchronized (this) {
6208            // Ensure that any processes we had put on hold are now started
6209            // up.
6210            final int NP = mProcessesOnHold.size();
6211            if (NP > 0) {
6212                ArrayList<ProcessRecord> procs =
6213                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6214                for (int ip=0; ip<NP; ip++) {
6215                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6216                            + procs.get(ip));
6217                    startProcessLocked(procs.get(ip), "on-hold", null);
6218                }
6219            }
6220
6221            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6222                // Start looking for apps that are abusing wake locks.
6223                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6224                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6225                // Tell anyone interested that we are done booting!
6226                SystemProperties.set("sys.boot_completed", "1");
6227                SystemProperties.set("dev.bootcomplete", "1");
6228                for (int i=0; i<mStartedUsers.size(); i++) {
6229                    UserStartedState uss = mStartedUsers.valueAt(i);
6230                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6231                        uss.mState = UserStartedState.STATE_RUNNING;
6232                        final int userId = mStartedUsers.keyAt(i);
6233                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6234                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6235                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6236                        broadcastIntentLocked(null, null, intent, null,
6237                                new IIntentReceiver.Stub() {
6238                                    @Override
6239                                    public void performReceive(Intent intent, int resultCode,
6240                                            String data, Bundle extras, boolean ordered,
6241                                            boolean sticky, int sendingUser) {
6242                                        synchronized (ActivityManagerService.this) {
6243                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6244                                                    true, false);
6245                                        }
6246                                    }
6247                                },
6248                                0, null, null,
6249                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6250                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6251                                userId);
6252                    }
6253                }
6254                scheduleStartProfilesLocked();
6255            }
6256        }
6257    }
6258
6259    final void ensureBootCompleted() {
6260        boolean booting;
6261        boolean enableScreen;
6262        synchronized (this) {
6263            booting = mBooting;
6264            mBooting = false;
6265            enableScreen = !mBooted;
6266            mBooted = true;
6267        }
6268
6269        if (booting) {
6270            finishBooting();
6271        }
6272
6273        if (enableScreen) {
6274            enableScreenAfterBoot();
6275        }
6276    }
6277
6278    @Override
6279    public final void activityResumed(IBinder token) {
6280        final long origId = Binder.clearCallingIdentity();
6281        synchronized(this) {
6282            ActivityStack stack = ActivityRecord.getStackLocked(token);
6283            if (stack != null) {
6284                ActivityRecord.activityResumedLocked(token);
6285            }
6286        }
6287        Binder.restoreCallingIdentity(origId);
6288    }
6289
6290    @Override
6291    public final void activityPaused(IBinder token) {
6292        final long origId = Binder.clearCallingIdentity();
6293        synchronized(this) {
6294            ActivityStack stack = ActivityRecord.getStackLocked(token);
6295            if (stack != null) {
6296                stack.activityPausedLocked(token, false);
6297            }
6298        }
6299        Binder.restoreCallingIdentity(origId);
6300    }
6301
6302    @Override
6303    public final void activityStopped(IBinder token, Bundle icicle,
6304            PersistableBundle persistentState, CharSequence description) {
6305        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6306
6307        // Refuse possible leaked file descriptors
6308        if (icicle != null && icicle.hasFileDescriptors()) {
6309            throw new IllegalArgumentException("File descriptors passed in Bundle");
6310        }
6311
6312        final long origId = Binder.clearCallingIdentity();
6313
6314        synchronized (this) {
6315            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6316            if (r != null) {
6317                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6318            }
6319        }
6320
6321        trimApplications();
6322
6323        Binder.restoreCallingIdentity(origId);
6324    }
6325
6326    @Override
6327    public final void activityDestroyed(IBinder token) {
6328        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6329        synchronized (this) {
6330            ActivityStack stack = ActivityRecord.getStackLocked(token);
6331            if (stack != null) {
6332                stack.activityDestroyedLocked(token);
6333            }
6334        }
6335    }
6336
6337    @Override
6338    public final void backgroundResourcesReleased(IBinder token) {
6339        final long origId = Binder.clearCallingIdentity();
6340        try {
6341            synchronized (this) {
6342                ActivityStack stack = ActivityRecord.getStackLocked(token);
6343                if (stack != null) {
6344                    stack.backgroundResourcesReleased(token);
6345                }
6346            }
6347        } finally {
6348            Binder.restoreCallingIdentity(origId);
6349        }
6350    }
6351
6352    @Override
6353    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6354        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6355    }
6356
6357    @Override
6358    public final void notifyEnterAnimationComplete(IBinder token) {
6359        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6360    }
6361
6362    @Override
6363    public String getCallingPackage(IBinder token) {
6364        synchronized (this) {
6365            ActivityRecord r = getCallingRecordLocked(token);
6366            return r != null ? r.info.packageName : null;
6367        }
6368    }
6369
6370    @Override
6371    public ComponentName getCallingActivity(IBinder token) {
6372        synchronized (this) {
6373            ActivityRecord r = getCallingRecordLocked(token);
6374            return r != null ? r.intent.getComponent() : null;
6375        }
6376    }
6377
6378    private ActivityRecord getCallingRecordLocked(IBinder token) {
6379        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6380        if (r == null) {
6381            return null;
6382        }
6383        return r.resultTo;
6384    }
6385
6386    @Override
6387    public ComponentName getActivityClassForToken(IBinder token) {
6388        synchronized(this) {
6389            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6390            if (r == null) {
6391                return null;
6392            }
6393            return r.intent.getComponent();
6394        }
6395    }
6396
6397    @Override
6398    public String getPackageForToken(IBinder token) {
6399        synchronized(this) {
6400            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6401            if (r == null) {
6402                return null;
6403            }
6404            return r.packageName;
6405        }
6406    }
6407
6408    @Override
6409    public IIntentSender getIntentSender(int type,
6410            String packageName, IBinder token, String resultWho,
6411            int requestCode, Intent[] intents, String[] resolvedTypes,
6412            int flags, Bundle options, int userId) {
6413        enforceNotIsolatedCaller("getIntentSender");
6414        // Refuse possible leaked file descriptors
6415        if (intents != null) {
6416            if (intents.length < 1) {
6417                throw new IllegalArgumentException("Intents array length must be >= 1");
6418            }
6419            for (int i=0; i<intents.length; i++) {
6420                Intent intent = intents[i];
6421                if (intent != null) {
6422                    if (intent.hasFileDescriptors()) {
6423                        throw new IllegalArgumentException("File descriptors passed in Intent");
6424                    }
6425                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6426                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6427                        throw new IllegalArgumentException(
6428                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6429                    }
6430                    intents[i] = new Intent(intent);
6431                }
6432            }
6433            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6434                throw new IllegalArgumentException(
6435                        "Intent array length does not match resolvedTypes length");
6436            }
6437        }
6438        if (options != null) {
6439            if (options.hasFileDescriptors()) {
6440                throw new IllegalArgumentException("File descriptors passed in options");
6441            }
6442        }
6443
6444        synchronized(this) {
6445            int callingUid = Binder.getCallingUid();
6446            int origUserId = userId;
6447            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6448                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6449                    ALLOW_NON_FULL, "getIntentSender", null);
6450            if (origUserId == UserHandle.USER_CURRENT) {
6451                // We don't want to evaluate this until the pending intent is
6452                // actually executed.  However, we do want to always do the
6453                // security checking for it above.
6454                userId = UserHandle.USER_CURRENT;
6455            }
6456            try {
6457                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6458                    int uid = AppGlobals.getPackageManager()
6459                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6460                    if (!UserHandle.isSameApp(callingUid, uid)) {
6461                        String msg = "Permission Denial: getIntentSender() from pid="
6462                            + Binder.getCallingPid()
6463                            + ", uid=" + Binder.getCallingUid()
6464                            + ", (need uid=" + uid + ")"
6465                            + " is not allowed to send as package " + packageName;
6466                        Slog.w(TAG, msg);
6467                        throw new SecurityException(msg);
6468                    }
6469                }
6470
6471                return getIntentSenderLocked(type, packageName, callingUid, userId,
6472                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6473
6474            } catch (RemoteException e) {
6475                throw new SecurityException(e);
6476            }
6477        }
6478    }
6479
6480    IIntentSender getIntentSenderLocked(int type, String packageName,
6481            int callingUid, int userId, IBinder token, String resultWho,
6482            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6483            Bundle options) {
6484        if (DEBUG_MU)
6485            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6486        ActivityRecord activity = null;
6487        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6488            activity = ActivityRecord.isInStackLocked(token);
6489            if (activity == null) {
6490                return null;
6491            }
6492            if (activity.finishing) {
6493                return null;
6494            }
6495        }
6496
6497        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6498        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6499        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6500        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6501                |PendingIntent.FLAG_UPDATE_CURRENT);
6502
6503        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6504                type, packageName, activity, resultWho,
6505                requestCode, intents, resolvedTypes, flags, options, userId);
6506        WeakReference<PendingIntentRecord> ref;
6507        ref = mIntentSenderRecords.get(key);
6508        PendingIntentRecord rec = ref != null ? ref.get() : null;
6509        if (rec != null) {
6510            if (!cancelCurrent) {
6511                if (updateCurrent) {
6512                    if (rec.key.requestIntent != null) {
6513                        rec.key.requestIntent.replaceExtras(intents != null ?
6514                                intents[intents.length - 1] : null);
6515                    }
6516                    if (intents != null) {
6517                        intents[intents.length-1] = rec.key.requestIntent;
6518                        rec.key.allIntents = intents;
6519                        rec.key.allResolvedTypes = resolvedTypes;
6520                    } else {
6521                        rec.key.allIntents = null;
6522                        rec.key.allResolvedTypes = null;
6523                    }
6524                }
6525                return rec;
6526            }
6527            rec.canceled = true;
6528            mIntentSenderRecords.remove(key);
6529        }
6530        if (noCreate) {
6531            return rec;
6532        }
6533        rec = new PendingIntentRecord(this, key, callingUid);
6534        mIntentSenderRecords.put(key, rec.ref);
6535        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6536            if (activity.pendingResults == null) {
6537                activity.pendingResults
6538                        = new HashSet<WeakReference<PendingIntentRecord>>();
6539            }
6540            activity.pendingResults.add(rec.ref);
6541        }
6542        return rec;
6543    }
6544
6545    @Override
6546    public void cancelIntentSender(IIntentSender sender) {
6547        if (!(sender instanceof PendingIntentRecord)) {
6548            return;
6549        }
6550        synchronized(this) {
6551            PendingIntentRecord rec = (PendingIntentRecord)sender;
6552            try {
6553                int uid = AppGlobals.getPackageManager()
6554                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6555                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6556                    String msg = "Permission Denial: cancelIntentSender() from pid="
6557                        + Binder.getCallingPid()
6558                        + ", uid=" + Binder.getCallingUid()
6559                        + " is not allowed to cancel packges "
6560                        + rec.key.packageName;
6561                    Slog.w(TAG, msg);
6562                    throw new SecurityException(msg);
6563                }
6564            } catch (RemoteException e) {
6565                throw new SecurityException(e);
6566            }
6567            cancelIntentSenderLocked(rec, true);
6568        }
6569    }
6570
6571    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6572        rec.canceled = true;
6573        mIntentSenderRecords.remove(rec.key);
6574        if (cleanActivity && rec.key.activity != null) {
6575            rec.key.activity.pendingResults.remove(rec.ref);
6576        }
6577    }
6578
6579    @Override
6580    public String getPackageForIntentSender(IIntentSender pendingResult) {
6581        if (!(pendingResult instanceof PendingIntentRecord)) {
6582            return null;
6583        }
6584        try {
6585            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6586            return res.key.packageName;
6587        } catch (ClassCastException e) {
6588        }
6589        return null;
6590    }
6591
6592    @Override
6593    public int getUidForIntentSender(IIntentSender sender) {
6594        if (sender instanceof PendingIntentRecord) {
6595            try {
6596                PendingIntentRecord res = (PendingIntentRecord)sender;
6597                return res.uid;
6598            } catch (ClassCastException e) {
6599            }
6600        }
6601        return -1;
6602    }
6603
6604    @Override
6605    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6606        if (!(pendingResult instanceof PendingIntentRecord)) {
6607            return false;
6608        }
6609        try {
6610            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6611            if (res.key.allIntents == null) {
6612                return false;
6613            }
6614            for (int i=0; i<res.key.allIntents.length; i++) {
6615                Intent intent = res.key.allIntents[i];
6616                if (intent.getPackage() != null && intent.getComponent() != null) {
6617                    return false;
6618                }
6619            }
6620            return true;
6621        } catch (ClassCastException e) {
6622        }
6623        return false;
6624    }
6625
6626    @Override
6627    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6628        if (!(pendingResult instanceof PendingIntentRecord)) {
6629            return false;
6630        }
6631        try {
6632            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6633            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6634                return true;
6635            }
6636            return false;
6637        } catch (ClassCastException e) {
6638        }
6639        return false;
6640    }
6641
6642    @Override
6643    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6644        if (!(pendingResult instanceof PendingIntentRecord)) {
6645            return null;
6646        }
6647        try {
6648            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6649            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6650        } catch (ClassCastException e) {
6651        }
6652        return null;
6653    }
6654
6655    @Override
6656    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6657        if (!(pendingResult instanceof PendingIntentRecord)) {
6658            return null;
6659        }
6660        try {
6661            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6662            Intent intent = res.key.requestIntent;
6663            if (intent != null) {
6664                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6665                        || res.lastTagPrefix.equals(prefix))) {
6666                    return res.lastTag;
6667                }
6668                res.lastTagPrefix = prefix;
6669                StringBuilder sb = new StringBuilder(128);
6670                if (prefix != null) {
6671                    sb.append(prefix);
6672                }
6673                if (intent.getAction() != null) {
6674                    sb.append(intent.getAction());
6675                } else if (intent.getComponent() != null) {
6676                    intent.getComponent().appendShortString(sb);
6677                } else {
6678                    sb.append("?");
6679                }
6680                return res.lastTag = sb.toString();
6681            }
6682        } catch (ClassCastException e) {
6683        }
6684        return null;
6685    }
6686
6687    @Override
6688    public void setProcessLimit(int max) {
6689        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6690                "setProcessLimit()");
6691        synchronized (this) {
6692            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6693            mProcessLimitOverride = max;
6694        }
6695        trimApplications();
6696    }
6697
6698    @Override
6699    public int getProcessLimit() {
6700        synchronized (this) {
6701            return mProcessLimitOverride;
6702        }
6703    }
6704
6705    void foregroundTokenDied(ForegroundToken token) {
6706        synchronized (ActivityManagerService.this) {
6707            synchronized (mPidsSelfLocked) {
6708                ForegroundToken cur
6709                    = mForegroundProcesses.get(token.pid);
6710                if (cur != token) {
6711                    return;
6712                }
6713                mForegroundProcesses.remove(token.pid);
6714                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6715                if (pr == null) {
6716                    return;
6717                }
6718                pr.forcingToForeground = null;
6719                updateProcessForegroundLocked(pr, false, false);
6720            }
6721            updateOomAdjLocked();
6722        }
6723    }
6724
6725    @Override
6726    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6727        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6728                "setProcessForeground()");
6729        synchronized(this) {
6730            boolean changed = false;
6731
6732            synchronized (mPidsSelfLocked) {
6733                ProcessRecord pr = mPidsSelfLocked.get(pid);
6734                if (pr == null && isForeground) {
6735                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6736                    return;
6737                }
6738                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6739                if (oldToken != null) {
6740                    oldToken.token.unlinkToDeath(oldToken, 0);
6741                    mForegroundProcesses.remove(pid);
6742                    if (pr != null) {
6743                        pr.forcingToForeground = null;
6744                    }
6745                    changed = true;
6746                }
6747                if (isForeground && token != null) {
6748                    ForegroundToken newToken = new ForegroundToken() {
6749                        @Override
6750                        public void binderDied() {
6751                            foregroundTokenDied(this);
6752                        }
6753                    };
6754                    newToken.pid = pid;
6755                    newToken.token = token;
6756                    try {
6757                        token.linkToDeath(newToken, 0);
6758                        mForegroundProcesses.put(pid, newToken);
6759                        pr.forcingToForeground = token;
6760                        changed = true;
6761                    } catch (RemoteException e) {
6762                        // If the process died while doing this, we will later
6763                        // do the cleanup with the process death link.
6764                    }
6765                }
6766            }
6767
6768            if (changed) {
6769                updateOomAdjLocked();
6770            }
6771        }
6772    }
6773
6774    // =========================================================
6775    // PERMISSIONS
6776    // =========================================================
6777
6778    static class PermissionController extends IPermissionController.Stub {
6779        ActivityManagerService mActivityManagerService;
6780        PermissionController(ActivityManagerService activityManagerService) {
6781            mActivityManagerService = activityManagerService;
6782        }
6783
6784        @Override
6785        public boolean checkPermission(String permission, int pid, int uid) {
6786            return mActivityManagerService.checkPermission(permission, pid,
6787                    uid) == PackageManager.PERMISSION_GRANTED;
6788        }
6789    }
6790
6791    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6792        @Override
6793        public int checkComponentPermission(String permission, int pid, int uid,
6794                int owningUid, boolean exported) {
6795            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6796                    owningUid, exported);
6797        }
6798
6799        @Override
6800        public Object getAMSLock() {
6801            return ActivityManagerService.this;
6802        }
6803    }
6804
6805    /**
6806     * This can be called with or without the global lock held.
6807     */
6808    int checkComponentPermission(String permission, int pid, int uid,
6809            int owningUid, boolean exported) {
6810        // We might be performing an operation on behalf of an indirect binder
6811        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6812        // client identity accordingly before proceeding.
6813        Identity tlsIdentity = sCallerIdentity.get();
6814        if (tlsIdentity != null) {
6815            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6816                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6817            uid = tlsIdentity.uid;
6818            pid = tlsIdentity.pid;
6819        }
6820
6821        if (pid == MY_PID) {
6822            return PackageManager.PERMISSION_GRANTED;
6823        }
6824
6825        return ActivityManager.checkComponentPermission(permission, uid,
6826                owningUid, exported);
6827    }
6828
6829    /**
6830     * As the only public entry point for permissions checking, this method
6831     * can enforce the semantic that requesting a check on a null global
6832     * permission is automatically denied.  (Internally a null permission
6833     * string is used when calling {@link #checkComponentPermission} in cases
6834     * when only uid-based security is needed.)
6835     *
6836     * This can be called with or without the global lock held.
6837     */
6838    @Override
6839    public int checkPermission(String permission, int pid, int uid) {
6840        if (permission == null) {
6841            return PackageManager.PERMISSION_DENIED;
6842        }
6843        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6844    }
6845
6846    /**
6847     * Binder IPC calls go through the public entry point.
6848     * This can be called with or without the global lock held.
6849     */
6850    int checkCallingPermission(String permission) {
6851        return checkPermission(permission,
6852                Binder.getCallingPid(),
6853                UserHandle.getAppId(Binder.getCallingUid()));
6854    }
6855
6856    /**
6857     * This can be called with or without the global lock held.
6858     */
6859    void enforceCallingPermission(String permission, String func) {
6860        if (checkCallingPermission(permission)
6861                == PackageManager.PERMISSION_GRANTED) {
6862            return;
6863        }
6864
6865        String msg = "Permission Denial: " + func + " from pid="
6866                + Binder.getCallingPid()
6867                + ", uid=" + Binder.getCallingUid()
6868                + " requires " + permission;
6869        Slog.w(TAG, msg);
6870        throw new SecurityException(msg);
6871    }
6872
6873    /**
6874     * Determine if UID is holding permissions required to access {@link Uri} in
6875     * the given {@link ProviderInfo}. Final permission checking is always done
6876     * in {@link ContentProvider}.
6877     */
6878    private final boolean checkHoldingPermissionsLocked(
6879            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6880        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6881                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6882        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6883            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6884                    != PERMISSION_GRANTED) {
6885                return false;
6886            }
6887        }
6888        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6889    }
6890
6891    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6892            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6893        if (pi.applicationInfo.uid == uid) {
6894            return true;
6895        } else if (!pi.exported) {
6896            return false;
6897        }
6898
6899        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6900        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6901        try {
6902            // check if target holds top-level <provider> permissions
6903            if (!readMet && pi.readPermission != null && considerUidPermissions
6904                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6905                readMet = true;
6906            }
6907            if (!writeMet && pi.writePermission != null && considerUidPermissions
6908                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6909                writeMet = true;
6910            }
6911
6912            // track if unprotected read/write is allowed; any denied
6913            // <path-permission> below removes this ability
6914            boolean allowDefaultRead = pi.readPermission == null;
6915            boolean allowDefaultWrite = pi.writePermission == null;
6916
6917            // check if target holds any <path-permission> that match uri
6918            final PathPermission[] pps = pi.pathPermissions;
6919            if (pps != null) {
6920                final String path = grantUri.uri.getPath();
6921                int i = pps.length;
6922                while (i > 0 && (!readMet || !writeMet)) {
6923                    i--;
6924                    PathPermission pp = pps[i];
6925                    if (pp.match(path)) {
6926                        if (!readMet) {
6927                            final String pprperm = pp.getReadPermission();
6928                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6929                                    + pprperm + " for " + pp.getPath()
6930                                    + ": match=" + pp.match(path)
6931                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6932                            if (pprperm != null) {
6933                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6934                                        == PERMISSION_GRANTED) {
6935                                    readMet = true;
6936                                } else {
6937                                    allowDefaultRead = false;
6938                                }
6939                            }
6940                        }
6941                        if (!writeMet) {
6942                            final String ppwperm = pp.getWritePermission();
6943                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6944                                    + ppwperm + " for " + pp.getPath()
6945                                    + ": match=" + pp.match(path)
6946                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6947                            if (ppwperm != null) {
6948                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6949                                        == PERMISSION_GRANTED) {
6950                                    writeMet = true;
6951                                } else {
6952                                    allowDefaultWrite = false;
6953                                }
6954                            }
6955                        }
6956                    }
6957                }
6958            }
6959
6960            // grant unprotected <provider> read/write, if not blocked by
6961            // <path-permission> above
6962            if (allowDefaultRead) readMet = true;
6963            if (allowDefaultWrite) writeMet = true;
6964
6965        } catch (RemoteException e) {
6966            return false;
6967        }
6968
6969        return readMet && writeMet;
6970    }
6971
6972    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6973        ProviderInfo pi = null;
6974        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6975        if (cpr != null) {
6976            pi = cpr.info;
6977        } else {
6978            try {
6979                pi = AppGlobals.getPackageManager().resolveContentProvider(
6980                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6981            } catch (RemoteException ex) {
6982            }
6983        }
6984        return pi;
6985    }
6986
6987    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6988        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6989        if (targetUris != null) {
6990            return targetUris.get(grantUri);
6991        }
6992        return null;
6993    }
6994
6995    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6996            String targetPkg, int targetUid, GrantUri grantUri) {
6997        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6998        if (targetUris == null) {
6999            targetUris = Maps.newArrayMap();
7000            mGrantedUriPermissions.put(targetUid, targetUris);
7001        }
7002
7003        UriPermission perm = targetUris.get(grantUri);
7004        if (perm == null) {
7005            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7006            targetUris.put(grantUri, perm);
7007        }
7008
7009        return perm;
7010    }
7011
7012    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7013            final int modeFlags) {
7014        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7015        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7016                : UriPermission.STRENGTH_OWNED;
7017
7018        // Root gets to do everything.
7019        if (uid == 0) {
7020            return true;
7021        }
7022
7023        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7024        if (perms == null) return false;
7025
7026        // First look for exact match
7027        final UriPermission exactPerm = perms.get(grantUri);
7028        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7029            return true;
7030        }
7031
7032        // No exact match, look for prefixes
7033        final int N = perms.size();
7034        for (int i = 0; i < N; i++) {
7035            final UriPermission perm = perms.valueAt(i);
7036            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7037                    && perm.getStrength(modeFlags) >= minStrength) {
7038                return true;
7039            }
7040        }
7041
7042        return false;
7043    }
7044
7045    /**
7046     * @param uri This uri must NOT contain an embedded userId.
7047     * @param userId The userId in which the uri is to be resolved.
7048     */
7049    @Override
7050    public int checkUriPermission(Uri uri, int pid, int uid,
7051            final int modeFlags, int userId) {
7052        enforceNotIsolatedCaller("checkUriPermission");
7053
7054        // Another redirected-binder-call permissions check as in
7055        // {@link checkComponentPermission}.
7056        Identity tlsIdentity = sCallerIdentity.get();
7057        if (tlsIdentity != null) {
7058            uid = tlsIdentity.uid;
7059            pid = tlsIdentity.pid;
7060        }
7061
7062        // Our own process gets to do everything.
7063        if (pid == MY_PID) {
7064            return PackageManager.PERMISSION_GRANTED;
7065        }
7066        synchronized (this) {
7067            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7068                    ? PackageManager.PERMISSION_GRANTED
7069                    : PackageManager.PERMISSION_DENIED;
7070        }
7071    }
7072
7073    /**
7074     * Check if the targetPkg can be granted permission to access uri by
7075     * the callingUid using the given modeFlags.  Throws a security exception
7076     * if callingUid is not allowed to do this.  Returns the uid of the target
7077     * if the URI permission grant should be performed; returns -1 if it is not
7078     * needed (for example targetPkg already has permission to access the URI).
7079     * If you already know the uid of the target, you can supply it in
7080     * lastTargetUid else set that to -1.
7081     */
7082    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7083            final int modeFlags, int lastTargetUid) {
7084        if (!Intent.isAccessUriMode(modeFlags)) {
7085            return -1;
7086        }
7087
7088        if (targetPkg != null) {
7089            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7090                    "Checking grant " + targetPkg + " permission to " + grantUri);
7091        }
7092
7093        final IPackageManager pm = AppGlobals.getPackageManager();
7094
7095        // If this is not a content: uri, we can't do anything with it.
7096        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7097            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7098                    "Can't grant URI permission for non-content URI: " + grantUri);
7099            return -1;
7100        }
7101
7102        final String authority = grantUri.uri.getAuthority();
7103        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7104        if (pi == null) {
7105            Slog.w(TAG, "No content provider found for permission check: " +
7106                    grantUri.uri.toSafeString());
7107            return -1;
7108        }
7109
7110        int targetUid = lastTargetUid;
7111        if (targetUid < 0 && targetPkg != null) {
7112            try {
7113                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7114                if (targetUid < 0) {
7115                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7116                            "Can't grant URI permission no uid for: " + targetPkg);
7117                    return -1;
7118                }
7119            } catch (RemoteException ex) {
7120                return -1;
7121            }
7122        }
7123
7124        if (targetUid >= 0) {
7125            // First...  does the target actually need this permission?
7126            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7127                // No need to grant the target this permission.
7128                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7129                        "Target " + targetPkg + " already has full permission to " + grantUri);
7130                return -1;
7131            }
7132        } else {
7133            // First...  there is no target package, so can anyone access it?
7134            boolean allowed = pi.exported;
7135            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7136                if (pi.readPermission != null) {
7137                    allowed = false;
7138                }
7139            }
7140            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7141                if (pi.writePermission != null) {
7142                    allowed = false;
7143                }
7144            }
7145            if (allowed) {
7146                return -1;
7147            }
7148        }
7149
7150        /* There is a special cross user grant if:
7151         * - The target is on another user.
7152         * - Apps on the current user can access the uri without any uid permissions.
7153         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7154         * grant uri permissions.
7155         */
7156        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7157                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7158                modeFlags, false /*without considering the uid permissions*/);
7159
7160        // Second...  is the provider allowing granting of URI permissions?
7161        if (!specialCrossUserGrant) {
7162            if (!pi.grantUriPermissions) {
7163                throw new SecurityException("Provider " + pi.packageName
7164                        + "/" + pi.name
7165                        + " does not allow granting of Uri permissions (uri "
7166                        + grantUri + ")");
7167            }
7168            if (pi.uriPermissionPatterns != null) {
7169                final int N = pi.uriPermissionPatterns.length;
7170                boolean allowed = false;
7171                for (int i=0; i<N; i++) {
7172                    if (pi.uriPermissionPatterns[i] != null
7173                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7174                        allowed = true;
7175                        break;
7176                    }
7177                }
7178                if (!allowed) {
7179                    throw new SecurityException("Provider " + pi.packageName
7180                            + "/" + pi.name
7181                            + " does not allow granting of permission to path of Uri "
7182                            + grantUri);
7183                }
7184            }
7185        }
7186
7187        // Third...  does the caller itself have permission to access
7188        // this uri?
7189        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7190            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7191                // Require they hold a strong enough Uri permission
7192                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7193                    throw new SecurityException("Uid " + callingUid
7194                            + " does not have permission to uri " + grantUri);
7195                }
7196            }
7197        }
7198        return targetUid;
7199    }
7200
7201    /**
7202     * @param uri This uri must NOT contain an embedded userId.
7203     * @param userId The userId in which the uri is to be resolved.
7204     */
7205    @Override
7206    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7207            final int modeFlags, int userId) {
7208        enforceNotIsolatedCaller("checkGrantUriPermission");
7209        synchronized(this) {
7210            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7211                    new GrantUri(userId, uri, false), modeFlags, -1);
7212        }
7213    }
7214
7215    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7216            final int modeFlags, UriPermissionOwner owner) {
7217        if (!Intent.isAccessUriMode(modeFlags)) {
7218            return;
7219        }
7220
7221        // So here we are: the caller has the assumed permission
7222        // to the uri, and the target doesn't.  Let's now give this to
7223        // the target.
7224
7225        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7226                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7227
7228        final String authority = grantUri.uri.getAuthority();
7229        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7230        if (pi == null) {
7231            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7232            return;
7233        }
7234
7235        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7236            grantUri.prefix = true;
7237        }
7238        final UriPermission perm = findOrCreateUriPermissionLocked(
7239                pi.packageName, targetPkg, targetUid, grantUri);
7240        perm.grantModes(modeFlags, owner);
7241    }
7242
7243    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7244            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7245        if (targetPkg == null) {
7246            throw new NullPointerException("targetPkg");
7247        }
7248        int targetUid;
7249        final IPackageManager pm = AppGlobals.getPackageManager();
7250        try {
7251            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7252        } catch (RemoteException ex) {
7253            return;
7254        }
7255
7256        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7257                targetUid);
7258        if (targetUid < 0) {
7259            return;
7260        }
7261
7262        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7263                owner);
7264    }
7265
7266    static class NeededUriGrants extends ArrayList<GrantUri> {
7267        final String targetPkg;
7268        final int targetUid;
7269        final int flags;
7270
7271        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7272            this.targetPkg = targetPkg;
7273            this.targetUid = targetUid;
7274            this.flags = flags;
7275        }
7276    }
7277
7278    /**
7279     * Like checkGrantUriPermissionLocked, but takes an Intent.
7280     */
7281    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7282            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7283        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7284                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7285                + " clip=" + (intent != null ? intent.getClipData() : null)
7286                + " from " + intent + "; flags=0x"
7287                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7288
7289        if (targetPkg == null) {
7290            throw new NullPointerException("targetPkg");
7291        }
7292
7293        if (intent == null) {
7294            return null;
7295        }
7296        Uri data = intent.getData();
7297        ClipData clip = intent.getClipData();
7298        if (data == null && clip == null) {
7299            return null;
7300        }
7301        // Default userId for uris in the intent (if they don't specify it themselves)
7302        int contentUserHint = intent.getContentUserHint();
7303        if (contentUserHint == UserHandle.USER_CURRENT) {
7304            contentUserHint = UserHandle.getUserId(callingUid);
7305        }
7306        final IPackageManager pm = AppGlobals.getPackageManager();
7307        int targetUid;
7308        if (needed != null) {
7309            targetUid = needed.targetUid;
7310        } else {
7311            try {
7312                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7313            } catch (RemoteException ex) {
7314                return null;
7315            }
7316            if (targetUid < 0) {
7317                if (DEBUG_URI_PERMISSION) {
7318                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7319                            + " on user " + targetUserId);
7320                }
7321                return null;
7322            }
7323        }
7324        if (data != null) {
7325            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7326            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7327                    targetUid);
7328            if (targetUid > 0) {
7329                if (needed == null) {
7330                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7331                }
7332                needed.add(grantUri);
7333            }
7334        }
7335        if (clip != null) {
7336            for (int i=0; i<clip.getItemCount(); i++) {
7337                Uri uri = clip.getItemAt(i).getUri();
7338                if (uri != null) {
7339                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7340                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7341                            targetUid);
7342                    if (targetUid > 0) {
7343                        if (needed == null) {
7344                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7345                        }
7346                        needed.add(grantUri);
7347                    }
7348                } else {
7349                    Intent clipIntent = clip.getItemAt(i).getIntent();
7350                    if (clipIntent != null) {
7351                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7352                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7353                        if (newNeeded != null) {
7354                            needed = newNeeded;
7355                        }
7356                    }
7357                }
7358            }
7359        }
7360
7361        return needed;
7362    }
7363
7364    /**
7365     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7366     */
7367    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7368            UriPermissionOwner owner) {
7369        if (needed != null) {
7370            for (int i=0; i<needed.size(); i++) {
7371                GrantUri grantUri = needed.get(i);
7372                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7373                        grantUri, needed.flags, owner);
7374            }
7375        }
7376    }
7377
7378    void grantUriPermissionFromIntentLocked(int callingUid,
7379            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7380        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7381                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7382        if (needed == null) {
7383            return;
7384        }
7385
7386        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7387    }
7388
7389    /**
7390     * @param uri This uri must NOT contain an embedded userId.
7391     * @param userId The userId in which the uri is to be resolved.
7392     */
7393    @Override
7394    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7395            final int modeFlags, int userId) {
7396        enforceNotIsolatedCaller("grantUriPermission");
7397        GrantUri grantUri = new GrantUri(userId, uri, false);
7398        synchronized(this) {
7399            final ProcessRecord r = getRecordForAppLocked(caller);
7400            if (r == null) {
7401                throw new SecurityException("Unable to find app for caller "
7402                        + caller
7403                        + " when granting permission to uri " + grantUri);
7404            }
7405            if (targetPkg == null) {
7406                throw new IllegalArgumentException("null target");
7407            }
7408            if (grantUri == null) {
7409                throw new IllegalArgumentException("null uri");
7410            }
7411
7412            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7413                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7414                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7415                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7416
7417            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7418                    UserHandle.getUserId(r.uid));
7419        }
7420    }
7421
7422    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7423        if (perm.modeFlags == 0) {
7424            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7425                    perm.targetUid);
7426            if (perms != null) {
7427                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7428                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7429
7430                perms.remove(perm.uri);
7431                if (perms.isEmpty()) {
7432                    mGrantedUriPermissions.remove(perm.targetUid);
7433                }
7434            }
7435        }
7436    }
7437
7438    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7439        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7440
7441        final IPackageManager pm = AppGlobals.getPackageManager();
7442        final String authority = grantUri.uri.getAuthority();
7443        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7444        if (pi == null) {
7445            Slog.w(TAG, "No content provider found for permission revoke: "
7446                    + grantUri.toSafeString());
7447            return;
7448        }
7449
7450        // Does the caller have this permission on the URI?
7451        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7452            // Right now, if you are not the original owner of the permission,
7453            // you are not allowed to revoke it.
7454            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
7455                throw new SecurityException("Uid " + callingUid
7456                        + " does not have permission to uri " + grantUri);
7457            //}
7458        }
7459
7460        boolean persistChanged = false;
7461
7462        // Go through all of the permissions and remove any that match.
7463        int N = mGrantedUriPermissions.size();
7464        for (int i = 0; i < N; i++) {
7465            final int targetUid = mGrantedUriPermissions.keyAt(i);
7466            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7467
7468            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7469                final UriPermission perm = it.next();
7470                if (perm.uri.sourceUserId == grantUri.sourceUserId
7471                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7472                    if (DEBUG_URI_PERMISSION)
7473                        Slog.v(TAG,
7474                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7475                    persistChanged |= perm.revokeModes(
7476                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7477                    if (perm.modeFlags == 0) {
7478                        it.remove();
7479                    }
7480                }
7481            }
7482
7483            if (perms.isEmpty()) {
7484                mGrantedUriPermissions.remove(targetUid);
7485                N--;
7486                i--;
7487            }
7488        }
7489
7490        if (persistChanged) {
7491            schedulePersistUriGrants();
7492        }
7493    }
7494
7495    /**
7496     * @param uri This uri must NOT contain an embedded userId.
7497     * @param userId The userId in which the uri is to be resolved.
7498     */
7499    @Override
7500    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7501            int userId) {
7502        enforceNotIsolatedCaller("revokeUriPermission");
7503        synchronized(this) {
7504            final ProcessRecord r = getRecordForAppLocked(caller);
7505            if (r == null) {
7506                throw new SecurityException("Unable to find app for caller "
7507                        + caller
7508                        + " when revoking permission to uri " + uri);
7509            }
7510            if (uri == null) {
7511                Slog.w(TAG, "revokeUriPermission: null uri");
7512                return;
7513            }
7514
7515            if (!Intent.isAccessUriMode(modeFlags)) {
7516                return;
7517            }
7518
7519            final IPackageManager pm = AppGlobals.getPackageManager();
7520            final String authority = uri.getAuthority();
7521            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7522            if (pi == null) {
7523                Slog.w(TAG, "No content provider found for permission revoke: "
7524                        + uri.toSafeString());
7525                return;
7526            }
7527
7528            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7529        }
7530    }
7531
7532    /**
7533     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7534     * given package.
7535     *
7536     * @param packageName Package name to match, or {@code null} to apply to all
7537     *            packages.
7538     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7539     *            to all users.
7540     * @param persistable If persistable grants should be removed.
7541     */
7542    private void removeUriPermissionsForPackageLocked(
7543            String packageName, int userHandle, boolean persistable) {
7544        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7545            throw new IllegalArgumentException("Must narrow by either package or user");
7546        }
7547
7548        boolean persistChanged = false;
7549
7550        int N = mGrantedUriPermissions.size();
7551        for (int i = 0; i < N; i++) {
7552            final int targetUid = mGrantedUriPermissions.keyAt(i);
7553            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7554
7555            // Only inspect grants matching user
7556            if (userHandle == UserHandle.USER_ALL
7557                    || userHandle == UserHandle.getUserId(targetUid)) {
7558                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7559                    final UriPermission perm = it.next();
7560
7561                    // Only inspect grants matching package
7562                    if (packageName == null || perm.sourcePkg.equals(packageName)
7563                            || perm.targetPkg.equals(packageName)) {
7564                        persistChanged |= perm.revokeModes(
7565                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7566
7567                        // Only remove when no modes remain; any persisted grants
7568                        // will keep this alive.
7569                        if (perm.modeFlags == 0) {
7570                            it.remove();
7571                        }
7572                    }
7573                }
7574
7575                if (perms.isEmpty()) {
7576                    mGrantedUriPermissions.remove(targetUid);
7577                    N--;
7578                    i--;
7579                }
7580            }
7581        }
7582
7583        if (persistChanged) {
7584            schedulePersistUriGrants();
7585        }
7586    }
7587
7588    @Override
7589    public IBinder newUriPermissionOwner(String name) {
7590        enforceNotIsolatedCaller("newUriPermissionOwner");
7591        synchronized(this) {
7592            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7593            return owner.getExternalTokenLocked();
7594        }
7595    }
7596
7597    /**
7598     * @param uri This uri must NOT contain an embedded userId.
7599     * @param sourceUserId The userId in which the uri is to be resolved.
7600     * @param targetUserId The userId of the app that receives the grant.
7601     */
7602    @Override
7603    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7604            final int modeFlags, int sourceUserId, int targetUserId) {
7605        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7606                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7607        synchronized(this) {
7608            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7609            if (owner == null) {
7610                throw new IllegalArgumentException("Unknown owner: " + token);
7611            }
7612            if (fromUid != Binder.getCallingUid()) {
7613                if (Binder.getCallingUid() != Process.myUid()) {
7614                    // Only system code can grant URI permissions on behalf
7615                    // of other users.
7616                    throw new SecurityException("nice try");
7617                }
7618            }
7619            if (targetPkg == null) {
7620                throw new IllegalArgumentException("null target");
7621            }
7622            if (uri == null) {
7623                throw new IllegalArgumentException("null uri");
7624            }
7625
7626            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7627                    modeFlags, owner, targetUserId);
7628        }
7629    }
7630
7631    /**
7632     * @param uri This uri must NOT contain an embedded userId.
7633     * @param userId The userId in which the uri is to be resolved.
7634     */
7635    @Override
7636    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7637        synchronized(this) {
7638            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7639            if (owner == null) {
7640                throw new IllegalArgumentException("Unknown owner: " + token);
7641            }
7642
7643            if (uri == null) {
7644                owner.removeUriPermissionsLocked(mode);
7645            } else {
7646                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7647            }
7648        }
7649    }
7650
7651    private void schedulePersistUriGrants() {
7652        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7653            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7654                    10 * DateUtils.SECOND_IN_MILLIS);
7655        }
7656    }
7657
7658    private void writeGrantedUriPermissions() {
7659        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7660
7661        // Snapshot permissions so we can persist without lock
7662        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7663        synchronized (this) {
7664            final int size = mGrantedUriPermissions.size();
7665            for (int i = 0; i < size; i++) {
7666                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7667                for (UriPermission perm : perms.values()) {
7668                    if (perm.persistedModeFlags != 0) {
7669                        persist.add(perm.snapshot());
7670                    }
7671                }
7672            }
7673        }
7674
7675        FileOutputStream fos = null;
7676        try {
7677            fos = mGrantFile.startWrite();
7678
7679            XmlSerializer out = new FastXmlSerializer();
7680            out.setOutput(fos, "utf-8");
7681            out.startDocument(null, true);
7682            out.startTag(null, TAG_URI_GRANTS);
7683            for (UriPermission.Snapshot perm : persist) {
7684                out.startTag(null, TAG_URI_GRANT);
7685                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7686                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7687                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7688                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7689                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7690                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7691                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7692                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7693                out.endTag(null, TAG_URI_GRANT);
7694            }
7695            out.endTag(null, TAG_URI_GRANTS);
7696            out.endDocument();
7697
7698            mGrantFile.finishWrite(fos);
7699        } catch (IOException e) {
7700            if (fos != null) {
7701                mGrantFile.failWrite(fos);
7702            }
7703        }
7704    }
7705
7706    private void readGrantedUriPermissionsLocked() {
7707        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7708
7709        final long now = System.currentTimeMillis();
7710
7711        FileInputStream fis = null;
7712        try {
7713            fis = mGrantFile.openRead();
7714            final XmlPullParser in = Xml.newPullParser();
7715            in.setInput(fis, null);
7716
7717            int type;
7718            while ((type = in.next()) != END_DOCUMENT) {
7719                final String tag = in.getName();
7720                if (type == START_TAG) {
7721                    if (TAG_URI_GRANT.equals(tag)) {
7722                        final int sourceUserId;
7723                        final int targetUserId;
7724                        final int userHandle = readIntAttribute(in,
7725                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7726                        if (userHandle != UserHandle.USER_NULL) {
7727                            // For backwards compatibility.
7728                            sourceUserId = userHandle;
7729                            targetUserId = userHandle;
7730                        } else {
7731                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7732                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7733                        }
7734                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7735                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7736                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7737                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7738                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7739                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7740
7741                        // Sanity check that provider still belongs to source package
7742                        final ProviderInfo pi = getProviderInfoLocked(
7743                                uri.getAuthority(), sourceUserId);
7744                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7745                            int targetUid = -1;
7746                            try {
7747                                targetUid = AppGlobals.getPackageManager()
7748                                        .getPackageUid(targetPkg, targetUserId);
7749                            } catch (RemoteException e) {
7750                            }
7751                            if (targetUid != -1) {
7752                                final UriPermission perm = findOrCreateUriPermissionLocked(
7753                                        sourcePkg, targetPkg, targetUid,
7754                                        new GrantUri(sourceUserId, uri, prefix));
7755                                perm.initPersistedModes(modeFlags, createdTime);
7756                            }
7757                        } else {
7758                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7759                                    + " but instead found " + pi);
7760                        }
7761                    }
7762                }
7763            }
7764        } catch (FileNotFoundException e) {
7765            // Missing grants is okay
7766        } catch (IOException e) {
7767            Log.wtf(TAG, "Failed reading Uri grants", e);
7768        } catch (XmlPullParserException e) {
7769            Log.wtf(TAG, "Failed reading Uri grants", e);
7770        } finally {
7771            IoUtils.closeQuietly(fis);
7772        }
7773    }
7774
7775    /**
7776     * @param uri This uri must NOT contain an embedded userId.
7777     * @param userId The userId in which the uri is to be resolved.
7778     */
7779    @Override
7780    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7781        enforceNotIsolatedCaller("takePersistableUriPermission");
7782
7783        Preconditions.checkFlagsArgument(modeFlags,
7784                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7785
7786        synchronized (this) {
7787            final int callingUid = Binder.getCallingUid();
7788            boolean persistChanged = false;
7789            GrantUri grantUri = new GrantUri(userId, uri, false);
7790
7791            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7792                    new GrantUri(userId, uri, false));
7793            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7794                    new GrantUri(userId, uri, true));
7795
7796            final boolean exactValid = (exactPerm != null)
7797                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7798            final boolean prefixValid = (prefixPerm != null)
7799                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7800
7801            if (!(exactValid || prefixValid)) {
7802                throw new SecurityException("No persistable permission grants found for UID "
7803                        + callingUid + " and Uri " + grantUri.toSafeString());
7804            }
7805
7806            if (exactValid) {
7807                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7808            }
7809            if (prefixValid) {
7810                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7811            }
7812
7813            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7814
7815            if (persistChanged) {
7816                schedulePersistUriGrants();
7817            }
7818        }
7819    }
7820
7821    /**
7822     * @param uri This uri must NOT contain an embedded userId.
7823     * @param userId The userId in which the uri is to be resolved.
7824     */
7825    @Override
7826    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7827        enforceNotIsolatedCaller("releasePersistableUriPermission");
7828
7829        Preconditions.checkFlagsArgument(modeFlags,
7830                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7831
7832        synchronized (this) {
7833            final int callingUid = Binder.getCallingUid();
7834            boolean persistChanged = false;
7835
7836            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7837                    new GrantUri(userId, uri, false));
7838            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7839                    new GrantUri(userId, uri, true));
7840            if (exactPerm == null && prefixPerm == null) {
7841                throw new SecurityException("No permission grants found for UID " + callingUid
7842                        + " and Uri " + uri.toSafeString());
7843            }
7844
7845            if (exactPerm != null) {
7846                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7847                removeUriPermissionIfNeededLocked(exactPerm);
7848            }
7849            if (prefixPerm != null) {
7850                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7851                removeUriPermissionIfNeededLocked(prefixPerm);
7852            }
7853
7854            if (persistChanged) {
7855                schedulePersistUriGrants();
7856            }
7857        }
7858    }
7859
7860    /**
7861     * Prune any older {@link UriPermission} for the given UID until outstanding
7862     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7863     *
7864     * @return if any mutations occured that require persisting.
7865     */
7866    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7867        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7868        if (perms == null) return false;
7869        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7870
7871        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7872        for (UriPermission perm : perms.values()) {
7873            if (perm.persistedModeFlags != 0) {
7874                persisted.add(perm);
7875            }
7876        }
7877
7878        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7879        if (trimCount <= 0) return false;
7880
7881        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7882        for (int i = 0; i < trimCount; i++) {
7883            final UriPermission perm = persisted.get(i);
7884
7885            if (DEBUG_URI_PERMISSION) {
7886                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7887            }
7888
7889            perm.releasePersistableModes(~0);
7890            removeUriPermissionIfNeededLocked(perm);
7891        }
7892
7893        return true;
7894    }
7895
7896    @Override
7897    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7898            String packageName, boolean incoming) {
7899        enforceNotIsolatedCaller("getPersistedUriPermissions");
7900        Preconditions.checkNotNull(packageName, "packageName");
7901
7902        final int callingUid = Binder.getCallingUid();
7903        final IPackageManager pm = AppGlobals.getPackageManager();
7904        try {
7905            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7906            if (packageUid != callingUid) {
7907                throw new SecurityException(
7908                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7909            }
7910        } catch (RemoteException e) {
7911            throw new SecurityException("Failed to verify package name ownership");
7912        }
7913
7914        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7915        synchronized (this) {
7916            if (incoming) {
7917                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7918                        callingUid);
7919                if (perms == null) {
7920                    Slog.w(TAG, "No permission grants found for " + packageName);
7921                } else {
7922                    for (UriPermission perm : perms.values()) {
7923                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7924                            result.add(perm.buildPersistedPublicApiObject());
7925                        }
7926                    }
7927                }
7928            } else {
7929                final int size = mGrantedUriPermissions.size();
7930                for (int i = 0; i < size; i++) {
7931                    final ArrayMap<GrantUri, UriPermission> perms =
7932                            mGrantedUriPermissions.valueAt(i);
7933                    for (UriPermission perm : perms.values()) {
7934                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7935                            result.add(perm.buildPersistedPublicApiObject());
7936                        }
7937                    }
7938                }
7939            }
7940        }
7941        return new ParceledListSlice<android.content.UriPermission>(result);
7942    }
7943
7944    @Override
7945    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7946        synchronized (this) {
7947            ProcessRecord app =
7948                who != null ? getRecordForAppLocked(who) : null;
7949            if (app == null) return;
7950
7951            Message msg = Message.obtain();
7952            msg.what = WAIT_FOR_DEBUGGER_MSG;
7953            msg.obj = app;
7954            msg.arg1 = waiting ? 1 : 0;
7955            mHandler.sendMessage(msg);
7956        }
7957    }
7958
7959    @Override
7960    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7961        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7962        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7963        outInfo.availMem = Process.getFreeMemory();
7964        outInfo.totalMem = Process.getTotalMemory();
7965        outInfo.threshold = homeAppMem;
7966        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7967        outInfo.hiddenAppThreshold = cachedAppMem;
7968        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7969                ProcessList.SERVICE_ADJ);
7970        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7971                ProcessList.VISIBLE_APP_ADJ);
7972        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7973                ProcessList.FOREGROUND_APP_ADJ);
7974    }
7975
7976    // =========================================================
7977    // TASK MANAGEMENT
7978    // =========================================================
7979
7980    @Override
7981    public List<IAppTask> getAppTasks(String callingPackage) {
7982        int callingUid = Binder.getCallingUid();
7983        long ident = Binder.clearCallingIdentity();
7984
7985        synchronized(this) {
7986            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7987            try {
7988                if (localLOGV) Slog.v(TAG, "getAppTasks");
7989
7990                final int N = mRecentTasks.size();
7991                for (int i = 0; i < N; i++) {
7992                    TaskRecord tr = mRecentTasks.get(i);
7993                    // Skip tasks that do not match the caller.  We don't need to verify
7994                    // callingPackage, because we are also limiting to callingUid and know
7995                    // that will limit to the correct security sandbox.
7996                    if (tr.effectiveUid != callingUid) {
7997                        continue;
7998                    }
7999                    Intent intent = tr.getBaseIntent();
8000                    if (intent == null ||
8001                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8002                        continue;
8003                    }
8004                    ActivityManager.RecentTaskInfo taskInfo =
8005                            createRecentTaskInfoFromTaskRecord(tr);
8006                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8007                    list.add(taskImpl);
8008                }
8009            } finally {
8010                Binder.restoreCallingIdentity(ident);
8011            }
8012            return list;
8013        }
8014    }
8015
8016    @Override
8017    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8018        final int callingUid = Binder.getCallingUid();
8019        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8020
8021        synchronized(this) {
8022            if (localLOGV) Slog.v(
8023                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8024
8025            final boolean allowed = checkCallingPermission(
8026                    android.Manifest.permission.GET_TASKS)
8027                    == PackageManager.PERMISSION_GRANTED;
8028            if (!allowed) {
8029                Slog.w(TAG, "getTasks: caller " + callingUid
8030                        + " does not hold GET_TASKS; limiting output");
8031            }
8032
8033            // TODO: Improve with MRU list from all ActivityStacks.
8034            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8035        }
8036
8037        return list;
8038    }
8039
8040    TaskRecord getMostRecentTask() {
8041        return mRecentTasks.get(0);
8042    }
8043
8044    /**
8045     * Creates a new RecentTaskInfo from a TaskRecord.
8046     */
8047    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8048        // Update the task description to reflect any changes in the task stack
8049        tr.updateTaskDescription();
8050
8051        // Compose the recent task info
8052        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8053        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8054        rti.persistentId = tr.taskId;
8055        rti.baseIntent = new Intent(tr.getBaseIntent());
8056        rti.origActivity = tr.origActivity;
8057        rti.description = tr.lastDescription;
8058        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8059        rti.userId = tr.userId;
8060        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8061        rti.firstActiveTime = tr.firstActiveTime;
8062        rti.lastActiveTime = tr.lastActiveTime;
8063        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8064        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8065        return rti;
8066    }
8067
8068    @Override
8069    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8070        final int callingUid = Binder.getCallingUid();
8071        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8072                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8073
8074        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8075        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8076        synchronized (this) {
8077            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
8078                    == PackageManager.PERMISSION_GRANTED;
8079            if (!allowed) {
8080                Slog.w(TAG, "getRecentTasks: caller " + callingUid
8081                        + " does not hold GET_TASKS; limiting output");
8082            }
8083            final boolean detailed = checkCallingPermission(
8084                    android.Manifest.permission.GET_DETAILED_TASKS)
8085                    == PackageManager.PERMISSION_GRANTED;
8086
8087            final int N = mRecentTasks.size();
8088            ArrayList<ActivityManager.RecentTaskInfo> res
8089                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8090                            maxNum < N ? maxNum : N);
8091
8092            final Set<Integer> includedUsers;
8093            if (includeProfiles) {
8094                includedUsers = getProfileIdsLocked(userId);
8095            } else {
8096                includedUsers = new HashSet<Integer>();
8097            }
8098            includedUsers.add(Integer.valueOf(userId));
8099
8100            for (int i=0; i<N && maxNum > 0; i++) {
8101                TaskRecord tr = mRecentTasks.get(i);
8102                // Only add calling user or related users recent tasks
8103                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8104                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8105                    continue;
8106                }
8107
8108                // Return the entry if desired by the caller.  We always return
8109                // the first entry, because callers always expect this to be the
8110                // foreground app.  We may filter others if the caller has
8111                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8112                // we should exclude the entry.
8113
8114                if (i == 0
8115                        || withExcluded
8116                        || (tr.intent == null)
8117                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8118                                == 0)) {
8119                    if (!allowed) {
8120                        // If the caller doesn't have the GET_TASKS permission, then only
8121                        // allow them to see a small subset of tasks -- their own and home.
8122                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8123                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8124                            continue;
8125                        }
8126                    }
8127                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8128                        if (tr.stack != null && tr.stack.isHomeStack()) {
8129                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8130                            continue;
8131                        }
8132                    }
8133                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8134                        // Don't include auto remove tasks that are finished or finishing.
8135                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8136                                + tr);
8137                        continue;
8138                    }
8139                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8140                            && !tr.isAvailable) {
8141                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8142                        continue;
8143                    }
8144
8145                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8146                    if (!detailed) {
8147                        rti.baseIntent.replaceExtras((Bundle)null);
8148                    }
8149
8150                    res.add(rti);
8151                    maxNum--;
8152                }
8153            }
8154            return res;
8155        }
8156    }
8157
8158    private TaskRecord recentTaskForIdLocked(int id) {
8159        final int N = mRecentTasks.size();
8160            for (int i=0; i<N; i++) {
8161                TaskRecord tr = mRecentTasks.get(i);
8162                if (tr.taskId == id) {
8163                    return tr;
8164                }
8165            }
8166            return null;
8167    }
8168
8169    @Override
8170    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8171        synchronized (this) {
8172            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8173                    "getTaskThumbnail()");
8174            TaskRecord tr = recentTaskForIdLocked(id);
8175            if (tr != null) {
8176                return tr.getTaskThumbnailLocked();
8177            }
8178        }
8179        return null;
8180    }
8181
8182    @Override
8183    public int addAppTask(IBinder activityToken, Intent intent,
8184            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8185        final int callingUid = Binder.getCallingUid();
8186        final long callingIdent = Binder.clearCallingIdentity();
8187
8188        try {
8189            synchronized (this) {
8190                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8191                if (r == null) {
8192                    throw new IllegalArgumentException("Activity does not exist; token="
8193                            + activityToken);
8194                }
8195                ComponentName comp = intent.getComponent();
8196                if (comp == null) {
8197                    throw new IllegalArgumentException("Intent " + intent
8198                            + " must specify explicit component");
8199                }
8200                if (thumbnail.getWidth() != mThumbnailWidth
8201                        || thumbnail.getHeight() != mThumbnailHeight) {
8202                    throw new IllegalArgumentException("Bad thumbnail size: got "
8203                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8204                            + mThumbnailWidth + "x" + mThumbnailHeight);
8205                }
8206                if (intent.getSelector() != null) {
8207                    intent.setSelector(null);
8208                }
8209                if (intent.getSourceBounds() != null) {
8210                    intent.setSourceBounds(null);
8211                }
8212                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8213                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8214                        // The caller has added this as an auto-remove task...  that makes no
8215                        // sense, so turn off auto-remove.
8216                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8217                    }
8218                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8219                    // Must be a new task.
8220                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8221                }
8222                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8223                    mLastAddedTaskActivity = null;
8224                }
8225                ActivityInfo ainfo = mLastAddedTaskActivity;
8226                if (ainfo == null) {
8227                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8228                            comp, 0, UserHandle.getUserId(callingUid));
8229                    if (ainfo.applicationInfo.uid != callingUid) {
8230                        throw new SecurityException(
8231                                "Can't add task for another application: target uid="
8232                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8233                    }
8234                }
8235
8236                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8237                        intent, description);
8238
8239                int trimIdx = trimRecentsForTask(task, false);
8240                if (trimIdx >= 0) {
8241                    // If this would have caused a trim, then we'll abort because that
8242                    // means it would be added at the end of the list but then just removed.
8243                    return -1;
8244                }
8245
8246                final int N = mRecentTasks.size();
8247                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8248                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8249                    tr.removedFromRecents(mTaskPersister);
8250                }
8251
8252                task.inRecents = true;
8253                mRecentTasks.add(task);
8254                r.task.stack.addTask(task, false, false);
8255
8256                task.setLastThumbnail(thumbnail);
8257                task.freeLastThumbnail();
8258
8259                return task.taskId;
8260            }
8261        } finally {
8262            Binder.restoreCallingIdentity(callingIdent);
8263        }
8264    }
8265
8266    @Override
8267    public Point getAppTaskThumbnailSize() {
8268        synchronized (this) {
8269            return new Point(mThumbnailWidth,  mThumbnailHeight);
8270        }
8271    }
8272
8273    @Override
8274    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8275        synchronized (this) {
8276            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8277            if (r != null) {
8278                r.taskDescription = td;
8279                r.task.updateTaskDescription();
8280            }
8281        }
8282    }
8283
8284    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
8285        mRecentTasks.remove(tr);
8286        tr.removedFromRecents(mTaskPersister);
8287        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
8288        Intent baseIntent = new Intent(
8289                tr.intent != null ? tr.intent : tr.affinityIntent);
8290        ComponentName component = baseIntent.getComponent();
8291        if (component == null) {
8292            Slog.w(TAG, "Now component for base intent of task: " + tr);
8293            return;
8294        }
8295
8296        // Find any running services associated with this app.
8297        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
8298
8299        if (killProcesses) {
8300            // Find any running processes associated with this app.
8301            final String pkg = component.getPackageName();
8302            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
8303            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8304            for (int i=0; i<pmap.size(); i++) {
8305                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8306                for (int j=0; j<uids.size(); j++) {
8307                    ProcessRecord proc = uids.valueAt(j);
8308                    if (proc.userId != tr.userId) {
8309                        continue;
8310                    }
8311                    if (!proc.pkgList.containsKey(pkg)) {
8312                        continue;
8313                    }
8314                    procs.add(proc);
8315                }
8316            }
8317
8318            // Kill the running processes.
8319            for (int i=0; i<procs.size(); i++) {
8320                ProcessRecord pr = procs.get(i);
8321                if (pr == mHomeProcess) {
8322                    // Don't kill the home process along with tasks from the same package.
8323                    continue;
8324                }
8325                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8326                    pr.kill("remove task", true);
8327                } else {
8328                    pr.waitingToKill = "remove task";
8329                }
8330            }
8331        }
8332    }
8333
8334    /**
8335     * Removes the task with the specified task id.
8336     *
8337     * @param taskId Identifier of the task to be removed.
8338     * @param flags Additional operational flags.  May be 0 or
8339     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
8340     * @return Returns true if the given task was found and removed.
8341     */
8342    private boolean removeTaskByIdLocked(int taskId, int flags) {
8343        TaskRecord tr = recentTaskForIdLocked(taskId);
8344        if (tr != null) {
8345            tr.removeTaskActivitiesLocked();
8346            cleanUpRemovedTaskLocked(tr, flags);
8347            if (tr.isPersistable) {
8348                notifyTaskPersisterLocked(null, true);
8349            }
8350            return true;
8351        }
8352        return false;
8353    }
8354
8355    @Override
8356    public boolean removeTask(int taskId, int flags) {
8357        synchronized (this) {
8358            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8359                    "removeTask()");
8360            long ident = Binder.clearCallingIdentity();
8361            try {
8362                return removeTaskByIdLocked(taskId, flags);
8363            } finally {
8364                Binder.restoreCallingIdentity(ident);
8365            }
8366        }
8367    }
8368
8369    /**
8370     * TODO: Add mController hook
8371     */
8372    @Override
8373    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8374        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8375                "moveTaskToFront()");
8376
8377        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8378        synchronized(this) {
8379            moveTaskToFrontLocked(taskId, flags, options);
8380        }
8381    }
8382
8383    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8384        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8385                Binder.getCallingUid(), "Task to front")) {
8386            ActivityOptions.abort(options);
8387            return;
8388        }
8389        final long origId = Binder.clearCallingIdentity();
8390        try {
8391            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8392            if (task == null) {
8393                return;
8394            }
8395            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8396                mStackSupervisor.showLockTaskToast();
8397                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8398                return;
8399            }
8400            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8401            if (prev != null && prev.isRecentsActivity()) {
8402                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8403            }
8404            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8405        } finally {
8406            Binder.restoreCallingIdentity(origId);
8407        }
8408        ActivityOptions.abort(options);
8409    }
8410
8411    @Override
8412    public void moveTaskToBack(int taskId) {
8413        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8414                "moveTaskToBack()");
8415
8416        synchronized(this) {
8417            TaskRecord tr = recentTaskForIdLocked(taskId);
8418            if (tr != null) {
8419                if (tr == mStackSupervisor.mLockTaskModeTask) {
8420                    mStackSupervisor.showLockTaskToast();
8421                    return;
8422                }
8423                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8424                ActivityStack stack = tr.stack;
8425                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8426                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8427                            Binder.getCallingUid(), "Task to back")) {
8428                        return;
8429                    }
8430                }
8431                final long origId = Binder.clearCallingIdentity();
8432                try {
8433                    stack.moveTaskToBackLocked(taskId, null);
8434                } finally {
8435                    Binder.restoreCallingIdentity(origId);
8436                }
8437            }
8438        }
8439    }
8440
8441    /**
8442     * Moves an activity, and all of the other activities within the same task, to the bottom
8443     * of the history stack.  The activity's order within the task is unchanged.
8444     *
8445     * @param token A reference to the activity we wish to move
8446     * @param nonRoot If false then this only works if the activity is the root
8447     *                of a task; if true it will work for any activity in a task.
8448     * @return Returns true if the move completed, false if not.
8449     */
8450    @Override
8451    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8452        enforceNotIsolatedCaller("moveActivityTaskToBack");
8453        synchronized(this) {
8454            final long origId = Binder.clearCallingIdentity();
8455            try {
8456                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8457                if (taskId >= 0) {
8458                    if ((mStackSupervisor.mLockTaskModeTask != null)
8459                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8460                        mStackSupervisor.showLockTaskToast();
8461                        return false;
8462                    }
8463                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8464                }
8465            } finally {
8466                Binder.restoreCallingIdentity(origId);
8467            }
8468        }
8469        return false;
8470    }
8471
8472    @Override
8473    public void moveTaskBackwards(int task) {
8474        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8475                "moveTaskBackwards()");
8476
8477        synchronized(this) {
8478            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8479                    Binder.getCallingUid(), "Task backwards")) {
8480                return;
8481            }
8482            final long origId = Binder.clearCallingIdentity();
8483            moveTaskBackwardsLocked(task);
8484            Binder.restoreCallingIdentity(origId);
8485        }
8486    }
8487
8488    private final void moveTaskBackwardsLocked(int task) {
8489        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8490    }
8491
8492    @Override
8493    public IBinder getHomeActivityToken() throws RemoteException {
8494        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8495                "getHomeActivityToken()");
8496        synchronized (this) {
8497            return mStackSupervisor.getHomeActivityToken();
8498        }
8499    }
8500
8501    @Override
8502    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8503            IActivityContainerCallback callback) throws RemoteException {
8504        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8505                "createActivityContainer()");
8506        synchronized (this) {
8507            if (parentActivityToken == null) {
8508                throw new IllegalArgumentException("parent token must not be null");
8509            }
8510            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8511            if (r == null) {
8512                return null;
8513            }
8514            if (callback == null) {
8515                throw new IllegalArgumentException("callback must not be null");
8516            }
8517            return mStackSupervisor.createActivityContainer(r, callback);
8518        }
8519    }
8520
8521    @Override
8522    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8523        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8524                "deleteActivityContainer()");
8525        synchronized (this) {
8526            mStackSupervisor.deleteActivityContainer(container);
8527        }
8528    }
8529
8530    @Override
8531    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8532            throws RemoteException {
8533        synchronized (this) {
8534            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8535            if (stack != null) {
8536                return stack.mActivityContainer;
8537            }
8538            return null;
8539        }
8540    }
8541
8542    @Override
8543    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8544        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8545                "moveTaskToStack()");
8546        if (stackId == HOME_STACK_ID) {
8547            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8548                    new RuntimeException("here").fillInStackTrace());
8549        }
8550        synchronized (this) {
8551            long ident = Binder.clearCallingIdentity();
8552            try {
8553                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8554                        + stackId + " toTop=" + toTop);
8555                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8556            } finally {
8557                Binder.restoreCallingIdentity(ident);
8558            }
8559        }
8560    }
8561
8562    @Override
8563    public void resizeStack(int stackBoxId, Rect bounds) {
8564        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8565                "resizeStackBox()");
8566        long ident = Binder.clearCallingIdentity();
8567        try {
8568            mWindowManager.resizeStack(stackBoxId, bounds);
8569        } finally {
8570            Binder.restoreCallingIdentity(ident);
8571        }
8572    }
8573
8574    @Override
8575    public List<StackInfo> getAllStackInfos() {
8576        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8577                "getAllStackInfos()");
8578        long ident = Binder.clearCallingIdentity();
8579        try {
8580            synchronized (this) {
8581                return mStackSupervisor.getAllStackInfosLocked();
8582            }
8583        } finally {
8584            Binder.restoreCallingIdentity(ident);
8585        }
8586    }
8587
8588    @Override
8589    public StackInfo getStackInfo(int stackId) {
8590        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8591                "getStackInfo()");
8592        long ident = Binder.clearCallingIdentity();
8593        try {
8594            synchronized (this) {
8595                return mStackSupervisor.getStackInfoLocked(stackId);
8596            }
8597        } finally {
8598            Binder.restoreCallingIdentity(ident);
8599        }
8600    }
8601
8602    @Override
8603    public boolean isInHomeStack(int taskId) {
8604        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8605                "getStackInfo()");
8606        long ident = Binder.clearCallingIdentity();
8607        try {
8608            synchronized (this) {
8609                TaskRecord tr = recentTaskForIdLocked(taskId);
8610                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8611            }
8612        } finally {
8613            Binder.restoreCallingIdentity(ident);
8614        }
8615    }
8616
8617    @Override
8618    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8619        synchronized(this) {
8620            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8621        }
8622    }
8623
8624    private boolean isLockTaskAuthorized(String pkg) {
8625        final DevicePolicyManager dpm = (DevicePolicyManager)
8626                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8627        try {
8628            int uid = mContext.getPackageManager().getPackageUid(pkg,
8629                    Binder.getCallingUserHandle().getIdentifier());
8630            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8631        } catch (NameNotFoundException e) {
8632            return false;
8633        }
8634    }
8635
8636    void startLockTaskMode(TaskRecord task) {
8637        final String pkg;
8638        synchronized (this) {
8639            pkg = task.intent.getComponent().getPackageName();
8640        }
8641        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8642        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8643            final TaskRecord taskRecord = task;
8644            mHandler.post(new Runnable() {
8645                @Override
8646                public void run() {
8647                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8648                }
8649            });
8650            return;
8651        }
8652        long ident = Binder.clearCallingIdentity();
8653        try {
8654            synchronized (this) {
8655                // Since we lost lock on task, make sure it is still there.
8656                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8657                if (task != null) {
8658                    if (!isSystemInitiated
8659                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8660                        throw new IllegalArgumentException("Invalid task, not in foreground");
8661                    }
8662                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8663                }
8664            }
8665        } finally {
8666            Binder.restoreCallingIdentity(ident);
8667        }
8668    }
8669
8670    @Override
8671    public void startLockTaskMode(int taskId) {
8672        final TaskRecord task;
8673        long ident = Binder.clearCallingIdentity();
8674        try {
8675            synchronized (this) {
8676                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8677            }
8678        } finally {
8679            Binder.restoreCallingIdentity(ident);
8680        }
8681        if (task != null) {
8682            startLockTaskMode(task);
8683        }
8684    }
8685
8686    @Override
8687    public void startLockTaskMode(IBinder token) {
8688        final TaskRecord task;
8689        long ident = Binder.clearCallingIdentity();
8690        try {
8691            synchronized (this) {
8692                final ActivityRecord r = ActivityRecord.forToken(token);
8693                if (r == null) {
8694                    return;
8695                }
8696                task = r.task;
8697            }
8698        } finally {
8699            Binder.restoreCallingIdentity(ident);
8700        }
8701        if (task != null) {
8702            startLockTaskMode(task);
8703        }
8704    }
8705
8706    @Override
8707    public void startLockTaskModeOnCurrent() throws RemoteException {
8708        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8709                "startLockTaskModeOnCurrent");
8710        ActivityRecord r = null;
8711        synchronized (this) {
8712            r = mStackSupervisor.topRunningActivityLocked();
8713        }
8714        startLockTaskMode(r.task);
8715    }
8716
8717    @Override
8718    public void stopLockTaskMode() {
8719        // Verify that the user matches the package of the intent for the TaskRecord
8720        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8721        // and stopLockTaskMode.
8722        final int callingUid = Binder.getCallingUid();
8723        if (callingUid != Process.SYSTEM_UID) {
8724            try {
8725                String pkg =
8726                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8727                int uid = mContext.getPackageManager().getPackageUid(pkg,
8728                        Binder.getCallingUserHandle().getIdentifier());
8729                if (uid != callingUid) {
8730                    throw new SecurityException("Invalid uid, expected " + uid);
8731                }
8732            } catch (NameNotFoundException e) {
8733                Log.d(TAG, "stopLockTaskMode " + e);
8734                return;
8735            }
8736        }
8737        long ident = Binder.clearCallingIdentity();
8738        try {
8739            Log.d(TAG, "stopLockTaskMode");
8740            // Stop lock task
8741            synchronized (this) {
8742                mStackSupervisor.setLockTaskModeLocked(null, false);
8743            }
8744        } finally {
8745            Binder.restoreCallingIdentity(ident);
8746        }
8747    }
8748
8749    @Override
8750    public void stopLockTaskModeOnCurrent() throws RemoteException {
8751        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8752                "stopLockTaskModeOnCurrent");
8753        long ident = Binder.clearCallingIdentity();
8754        try {
8755            stopLockTaskMode();
8756        } finally {
8757            Binder.restoreCallingIdentity(ident);
8758        }
8759    }
8760
8761    @Override
8762    public boolean isInLockTaskMode() {
8763        synchronized (this) {
8764            return mStackSupervisor.isInLockTaskMode();
8765        }
8766    }
8767
8768    // =========================================================
8769    // CONTENT PROVIDERS
8770    // =========================================================
8771
8772    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8773        List<ProviderInfo> providers = null;
8774        try {
8775            providers = AppGlobals.getPackageManager().
8776                queryContentProviders(app.processName, app.uid,
8777                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8778        } catch (RemoteException ex) {
8779        }
8780        if (DEBUG_MU)
8781            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8782        int userId = app.userId;
8783        if (providers != null) {
8784            int N = providers.size();
8785            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8786            for (int i=0; i<N; i++) {
8787                ProviderInfo cpi =
8788                    (ProviderInfo)providers.get(i);
8789                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8790                        cpi.name, cpi.flags);
8791                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8792                    // This is a singleton provider, but a user besides the
8793                    // default user is asking to initialize a process it runs
8794                    // in...  well, no, it doesn't actually run in this process,
8795                    // it runs in the process of the default user.  Get rid of it.
8796                    providers.remove(i);
8797                    N--;
8798                    i--;
8799                    continue;
8800                }
8801
8802                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8803                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8804                if (cpr == null) {
8805                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8806                    mProviderMap.putProviderByClass(comp, cpr);
8807                }
8808                if (DEBUG_MU)
8809                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8810                app.pubProviders.put(cpi.name, cpr);
8811                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8812                    // Don't add this if it is a platform component that is marked
8813                    // to run in multiple processes, because this is actually
8814                    // part of the framework so doesn't make sense to track as a
8815                    // separate apk in the process.
8816                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8817                            mProcessStats);
8818                }
8819                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8820            }
8821        }
8822        return providers;
8823    }
8824
8825    /**
8826     * Check if {@link ProcessRecord} has a possible chance at accessing the
8827     * given {@link ProviderInfo}. Final permission checking is always done
8828     * in {@link ContentProvider}.
8829     */
8830    private final String checkContentProviderPermissionLocked(
8831            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8832        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8833        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8834        boolean checkedGrants = false;
8835        if (checkUser) {
8836            // Looking for cross-user grants before enforcing the typical cross-users permissions
8837            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8838            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8839                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8840                    return null;
8841                }
8842                checkedGrants = true;
8843            }
8844            userId = handleIncomingUser(callingPid, callingUid, userId,
8845                    false, ALLOW_NON_FULL,
8846                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8847            if (userId != tmpTargetUserId) {
8848                // When we actually went to determine the final targer user ID, this ended
8849                // up different than our initial check for the authority.  This is because
8850                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8851                // SELF.  So we need to re-check the grants again.
8852                checkedGrants = false;
8853            }
8854        }
8855        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8856                cpi.applicationInfo.uid, cpi.exported)
8857                == PackageManager.PERMISSION_GRANTED) {
8858            return null;
8859        }
8860        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8861                cpi.applicationInfo.uid, cpi.exported)
8862                == PackageManager.PERMISSION_GRANTED) {
8863            return null;
8864        }
8865
8866        PathPermission[] pps = cpi.pathPermissions;
8867        if (pps != null) {
8868            int i = pps.length;
8869            while (i > 0) {
8870                i--;
8871                PathPermission pp = pps[i];
8872                String pprperm = pp.getReadPermission();
8873                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8874                        cpi.applicationInfo.uid, cpi.exported)
8875                        == PackageManager.PERMISSION_GRANTED) {
8876                    return null;
8877                }
8878                String ppwperm = pp.getWritePermission();
8879                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8880                        cpi.applicationInfo.uid, cpi.exported)
8881                        == PackageManager.PERMISSION_GRANTED) {
8882                    return null;
8883                }
8884            }
8885        }
8886        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8887            return null;
8888        }
8889
8890        String msg;
8891        if (!cpi.exported) {
8892            msg = "Permission Denial: opening provider " + cpi.name
8893                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8894                    + ", uid=" + callingUid + ") that is not exported from uid "
8895                    + cpi.applicationInfo.uid;
8896        } else {
8897            msg = "Permission Denial: opening provider " + cpi.name
8898                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8899                    + ", uid=" + callingUid + ") requires "
8900                    + cpi.readPermission + " or " + cpi.writePermission;
8901        }
8902        Slog.w(TAG, msg);
8903        return msg;
8904    }
8905
8906    /**
8907     * Returns if the ContentProvider has granted a uri to callingUid
8908     */
8909    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8910        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8911        if (perms != null) {
8912            for (int i=perms.size()-1; i>=0; i--) {
8913                GrantUri grantUri = perms.keyAt(i);
8914                if (grantUri.sourceUserId == userId || !checkUser) {
8915                    if (matchesProvider(grantUri.uri, cpi)) {
8916                        return true;
8917                    }
8918                }
8919            }
8920        }
8921        return false;
8922    }
8923
8924    /**
8925     * Returns true if the uri authority is one of the authorities specified in the provider.
8926     */
8927    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8928        String uriAuth = uri.getAuthority();
8929        String cpiAuth = cpi.authority;
8930        if (cpiAuth.indexOf(';') == -1) {
8931            return cpiAuth.equals(uriAuth);
8932        }
8933        String[] cpiAuths = cpiAuth.split(";");
8934        int length = cpiAuths.length;
8935        for (int i = 0; i < length; i++) {
8936            if (cpiAuths[i].equals(uriAuth)) return true;
8937        }
8938        return false;
8939    }
8940
8941    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8942            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8943        if (r != null) {
8944            for (int i=0; i<r.conProviders.size(); i++) {
8945                ContentProviderConnection conn = r.conProviders.get(i);
8946                if (conn.provider == cpr) {
8947                    if (DEBUG_PROVIDER) Slog.v(TAG,
8948                            "Adding provider requested by "
8949                            + r.processName + " from process "
8950                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8951                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8952                    if (stable) {
8953                        conn.stableCount++;
8954                        conn.numStableIncs++;
8955                    } else {
8956                        conn.unstableCount++;
8957                        conn.numUnstableIncs++;
8958                    }
8959                    return conn;
8960                }
8961            }
8962            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8963            if (stable) {
8964                conn.stableCount = 1;
8965                conn.numStableIncs = 1;
8966            } else {
8967                conn.unstableCount = 1;
8968                conn.numUnstableIncs = 1;
8969            }
8970            cpr.connections.add(conn);
8971            r.conProviders.add(conn);
8972            return conn;
8973        }
8974        cpr.addExternalProcessHandleLocked(externalProcessToken);
8975        return null;
8976    }
8977
8978    boolean decProviderCountLocked(ContentProviderConnection conn,
8979            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8980        if (conn != null) {
8981            cpr = conn.provider;
8982            if (DEBUG_PROVIDER) Slog.v(TAG,
8983                    "Removing provider requested by "
8984                    + conn.client.processName + " from process "
8985                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8986                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8987            if (stable) {
8988                conn.stableCount--;
8989            } else {
8990                conn.unstableCount--;
8991            }
8992            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8993                cpr.connections.remove(conn);
8994                conn.client.conProviders.remove(conn);
8995                return true;
8996            }
8997            return false;
8998        }
8999        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9000        return false;
9001    }
9002
9003    private void checkTime(long startTime, String where) {
9004        long now = SystemClock.elapsedRealtime();
9005        if ((now-startTime) > 1000) {
9006            // If we are taking more than a second, log about it.
9007            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9008        }
9009    }
9010
9011    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9012            String name, IBinder token, boolean stable, int userId) {
9013        ContentProviderRecord cpr;
9014        ContentProviderConnection conn = null;
9015        ProviderInfo cpi = null;
9016
9017        synchronized(this) {
9018            long startTime = SystemClock.elapsedRealtime();
9019
9020            ProcessRecord r = null;
9021            if (caller != null) {
9022                r = getRecordForAppLocked(caller);
9023                if (r == null) {
9024                    throw new SecurityException(
9025                            "Unable to find app for caller " + caller
9026                          + " (pid=" + Binder.getCallingPid()
9027                          + ") when getting content provider " + name);
9028                }
9029            }
9030
9031            boolean checkCrossUser = true;
9032
9033            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9034
9035            // First check if this content provider has been published...
9036            cpr = mProviderMap.getProviderByName(name, userId);
9037            // If that didn't work, check if it exists for user 0 and then
9038            // verify that it's a singleton provider before using it.
9039            if (cpr == null && userId != UserHandle.USER_OWNER) {
9040                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9041                if (cpr != null) {
9042                    cpi = cpr.info;
9043                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9044                            cpi.name, cpi.flags)
9045                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9046                        userId = UserHandle.USER_OWNER;
9047                        checkCrossUser = false;
9048                    } else {
9049                        cpr = null;
9050                        cpi = null;
9051                    }
9052                }
9053            }
9054
9055            boolean providerRunning = cpr != null;
9056            if (providerRunning) {
9057                cpi = cpr.info;
9058                String msg;
9059                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9060                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9061                        != null) {
9062                    throw new SecurityException(msg);
9063                }
9064                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9065
9066                if (r != null && cpr.canRunHere(r)) {
9067                    // This provider has been published or is in the process
9068                    // of being published...  but it is also allowed to run
9069                    // in the caller's process, so don't make a connection
9070                    // and just let the caller instantiate its own instance.
9071                    ContentProviderHolder holder = cpr.newHolder(null);
9072                    // don't give caller the provider object, it needs
9073                    // to make its own.
9074                    holder.provider = null;
9075                    return holder;
9076                }
9077
9078                final long origId = Binder.clearCallingIdentity();
9079
9080                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9081
9082                // In this case the provider instance already exists, so we can
9083                // return it right away.
9084                conn = incProviderCountLocked(r, cpr, token, stable);
9085                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9086                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9087                        // If this is a perceptible app accessing the provider,
9088                        // make sure to count it as being accessed and thus
9089                        // back up on the LRU list.  This is good because
9090                        // content providers are often expensive to start.
9091                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9092                        updateLruProcessLocked(cpr.proc, false, null);
9093                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9094                    }
9095                }
9096
9097                if (cpr.proc != null) {
9098                    if (false) {
9099                        if (cpr.name.flattenToShortString().equals(
9100                                "com.android.providers.calendar/.CalendarProvider2")) {
9101                            Slog.v(TAG, "****************** KILLING "
9102                                + cpr.name.flattenToShortString());
9103                            Process.killProcess(cpr.proc.pid);
9104                        }
9105                    }
9106                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9107                    boolean success = updateOomAdjLocked(cpr.proc);
9108                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9109                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9110                    // NOTE: there is still a race here where a signal could be
9111                    // pending on the process even though we managed to update its
9112                    // adj level.  Not sure what to do about this, but at least
9113                    // the race is now smaller.
9114                    if (!success) {
9115                        // Uh oh...  it looks like the provider's process
9116                        // has been killed on us.  We need to wait for a new
9117                        // process to be started, and make sure its death
9118                        // doesn't kill our process.
9119                        Slog.i(TAG,
9120                                "Existing provider " + cpr.name.flattenToShortString()
9121                                + " is crashing; detaching " + r);
9122                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9123                        checkTime(startTime, "getContentProviderImpl: before appDied");
9124                        appDiedLocked(cpr.proc);
9125                        checkTime(startTime, "getContentProviderImpl: after appDied");
9126                        if (!lastRef) {
9127                            // This wasn't the last ref our process had on
9128                            // the provider...  we have now been killed, bail.
9129                            return null;
9130                        }
9131                        providerRunning = false;
9132                        conn = null;
9133                    }
9134                }
9135
9136                Binder.restoreCallingIdentity(origId);
9137            }
9138
9139            boolean singleton;
9140            if (!providerRunning) {
9141                try {
9142                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9143                    cpi = AppGlobals.getPackageManager().
9144                        resolveContentProvider(name,
9145                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9146                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9147                } catch (RemoteException ex) {
9148                }
9149                if (cpi == null) {
9150                    return null;
9151                }
9152                // If the provider is a singleton AND
9153                // (it's a call within the same user || the provider is a
9154                // privileged app)
9155                // Then allow connecting to the singleton provider
9156                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9157                        cpi.name, cpi.flags)
9158                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9159                if (singleton) {
9160                    userId = UserHandle.USER_OWNER;
9161                }
9162                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9163                checkTime(startTime, "getContentProviderImpl: got app info for user");
9164
9165                String msg;
9166                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9167                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9168                        != null) {
9169                    throw new SecurityException(msg);
9170                }
9171                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9172
9173                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9174                        && !cpi.processName.equals("system")) {
9175                    // If this content provider does not run in the system
9176                    // process, and the system is not yet ready to run other
9177                    // processes, then fail fast instead of hanging.
9178                    throw new IllegalArgumentException(
9179                            "Attempt to launch content provider before system ready");
9180                }
9181
9182                // Make sure that the user who owns this provider is started.  If not,
9183                // we don't want to allow it to run.
9184                if (mStartedUsers.get(userId) == null) {
9185                    Slog.w(TAG, "Unable to launch app "
9186                            + cpi.applicationInfo.packageName + "/"
9187                            + cpi.applicationInfo.uid + " for provider "
9188                            + name + ": user " + userId + " is stopped");
9189                    return null;
9190                }
9191
9192                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9193                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9194                cpr = mProviderMap.getProviderByClass(comp, userId);
9195                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9196                final boolean firstClass = cpr == null;
9197                if (firstClass) {
9198                    try {
9199                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9200                        ApplicationInfo ai =
9201                            AppGlobals.getPackageManager().
9202                                getApplicationInfo(
9203                                        cpi.applicationInfo.packageName,
9204                                        STOCK_PM_FLAGS, userId);
9205                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9206                        if (ai == null) {
9207                            Slog.w(TAG, "No package info for content provider "
9208                                    + cpi.name);
9209                            return null;
9210                        }
9211                        ai = getAppInfoForUser(ai, userId);
9212                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9213                    } catch (RemoteException ex) {
9214                        // pm is in same process, this will never happen.
9215                    }
9216                }
9217
9218                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9219
9220                if (r != null && cpr.canRunHere(r)) {
9221                    // If this is a multiprocess provider, then just return its
9222                    // info and allow the caller to instantiate it.  Only do
9223                    // this if the provider is the same user as the caller's
9224                    // process, or can run as root (so can be in any process).
9225                    return cpr.newHolder(null);
9226                }
9227
9228                if (DEBUG_PROVIDER) {
9229                    RuntimeException e = new RuntimeException("here");
9230                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9231                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9232                }
9233
9234                // This is single process, and our app is now connecting to it.
9235                // See if we are already in the process of launching this
9236                // provider.
9237                final int N = mLaunchingProviders.size();
9238                int i;
9239                for (i=0; i<N; i++) {
9240                    if (mLaunchingProviders.get(i) == cpr) {
9241                        break;
9242                    }
9243                }
9244
9245                // If the provider is not already being launched, then get it
9246                // started.
9247                if (i >= N) {
9248                    final long origId = Binder.clearCallingIdentity();
9249
9250                    try {
9251                        // Content provider is now in use, its package can't be stopped.
9252                        try {
9253                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9254                            AppGlobals.getPackageManager().setPackageStoppedState(
9255                                    cpr.appInfo.packageName, false, userId);
9256                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9257                        } catch (RemoteException e) {
9258                        } catch (IllegalArgumentException e) {
9259                            Slog.w(TAG, "Failed trying to unstop package "
9260                                    + cpr.appInfo.packageName + ": " + e);
9261                        }
9262
9263                        // Use existing process if already started
9264                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9265                        ProcessRecord proc = getProcessRecordLocked(
9266                                cpi.processName, cpr.appInfo.uid, false);
9267                        if (proc != null && proc.thread != null) {
9268                            if (DEBUG_PROVIDER) {
9269                                Slog.d(TAG, "Installing in existing process " + proc);
9270                            }
9271                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9272                            proc.pubProviders.put(cpi.name, cpr);
9273                            try {
9274                                proc.thread.scheduleInstallProvider(cpi);
9275                            } catch (RemoteException e) {
9276                            }
9277                        } else {
9278                            checkTime(startTime, "getContentProviderImpl: before start process");
9279                            proc = startProcessLocked(cpi.processName,
9280                                    cpr.appInfo, false, 0, "content provider",
9281                                    new ComponentName(cpi.applicationInfo.packageName,
9282                                            cpi.name), false, false, false);
9283                            checkTime(startTime, "getContentProviderImpl: after start process");
9284                            if (proc == null) {
9285                                Slog.w(TAG, "Unable to launch app "
9286                                        + cpi.applicationInfo.packageName + "/"
9287                                        + cpi.applicationInfo.uid + " for provider "
9288                                        + name + ": process is bad");
9289                                return null;
9290                            }
9291                        }
9292                        cpr.launchingApp = proc;
9293                        mLaunchingProviders.add(cpr);
9294                    } finally {
9295                        Binder.restoreCallingIdentity(origId);
9296                    }
9297                }
9298
9299                checkTime(startTime, "getContentProviderImpl: updating data structures");
9300
9301                // Make sure the provider is published (the same provider class
9302                // may be published under multiple names).
9303                if (firstClass) {
9304                    mProviderMap.putProviderByClass(comp, cpr);
9305                }
9306
9307                mProviderMap.putProviderByName(name, cpr);
9308                conn = incProviderCountLocked(r, cpr, token, stable);
9309                if (conn != null) {
9310                    conn.waiting = true;
9311                }
9312            }
9313            checkTime(startTime, "getContentProviderImpl: done!");
9314        }
9315
9316        // Wait for the provider to be published...
9317        synchronized (cpr) {
9318            while (cpr.provider == null) {
9319                if (cpr.launchingApp == null) {
9320                    Slog.w(TAG, "Unable to launch app "
9321                            + cpi.applicationInfo.packageName + "/"
9322                            + cpi.applicationInfo.uid + " for provider "
9323                            + name + ": launching app became null");
9324                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9325                            UserHandle.getUserId(cpi.applicationInfo.uid),
9326                            cpi.applicationInfo.packageName,
9327                            cpi.applicationInfo.uid, name);
9328                    return null;
9329                }
9330                try {
9331                    if (DEBUG_MU) {
9332                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9333                                + cpr.launchingApp);
9334                    }
9335                    if (conn != null) {
9336                        conn.waiting = true;
9337                    }
9338                    cpr.wait();
9339                } catch (InterruptedException ex) {
9340                } finally {
9341                    if (conn != null) {
9342                        conn.waiting = false;
9343                    }
9344                }
9345            }
9346        }
9347        return cpr != null ? cpr.newHolder(conn) : null;
9348    }
9349
9350    @Override
9351    public final ContentProviderHolder getContentProvider(
9352            IApplicationThread caller, String name, int userId, boolean stable) {
9353        enforceNotIsolatedCaller("getContentProvider");
9354        if (caller == null) {
9355            String msg = "null IApplicationThread when getting content provider "
9356                    + name;
9357            Slog.w(TAG, msg);
9358            throw new SecurityException(msg);
9359        }
9360        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9361        // with cross-user grant.
9362        return getContentProviderImpl(caller, name, null, stable, userId);
9363    }
9364
9365    public ContentProviderHolder getContentProviderExternal(
9366            String name, int userId, IBinder token) {
9367        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9368            "Do not have permission in call getContentProviderExternal()");
9369        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9370                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9371        return getContentProviderExternalUnchecked(name, token, userId);
9372    }
9373
9374    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9375            IBinder token, int userId) {
9376        return getContentProviderImpl(null, name, token, true, userId);
9377    }
9378
9379    /**
9380     * Drop a content provider from a ProcessRecord's bookkeeping
9381     */
9382    public void removeContentProvider(IBinder connection, boolean stable) {
9383        enforceNotIsolatedCaller("removeContentProvider");
9384        long ident = Binder.clearCallingIdentity();
9385        try {
9386            synchronized (this) {
9387                ContentProviderConnection conn;
9388                try {
9389                    conn = (ContentProviderConnection)connection;
9390                } catch (ClassCastException e) {
9391                    String msg ="removeContentProvider: " + connection
9392                            + " not a ContentProviderConnection";
9393                    Slog.w(TAG, msg);
9394                    throw new IllegalArgumentException(msg);
9395                }
9396                if (conn == null) {
9397                    throw new NullPointerException("connection is null");
9398                }
9399                if (decProviderCountLocked(conn, null, null, stable)) {
9400                    updateOomAdjLocked();
9401                }
9402            }
9403        } finally {
9404            Binder.restoreCallingIdentity(ident);
9405        }
9406    }
9407
9408    public void removeContentProviderExternal(String name, IBinder token) {
9409        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9410            "Do not have permission in call removeContentProviderExternal()");
9411        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
9412    }
9413
9414    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9415        synchronized (this) {
9416            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9417            if(cpr == null) {
9418                //remove from mProvidersByClass
9419                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9420                return;
9421            }
9422
9423            //update content provider record entry info
9424            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9425            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9426            if (localCpr.hasExternalProcessHandles()) {
9427                if (localCpr.removeExternalProcessHandleLocked(token)) {
9428                    updateOomAdjLocked();
9429                } else {
9430                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9431                            + " with no external reference for token: "
9432                            + token + ".");
9433                }
9434            } else {
9435                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9436                        + " with no external references.");
9437            }
9438        }
9439    }
9440
9441    public final void publishContentProviders(IApplicationThread caller,
9442            List<ContentProviderHolder> providers) {
9443        if (providers == null) {
9444            return;
9445        }
9446
9447        enforceNotIsolatedCaller("publishContentProviders");
9448        synchronized (this) {
9449            final ProcessRecord r = getRecordForAppLocked(caller);
9450            if (DEBUG_MU)
9451                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9452            if (r == null) {
9453                throw new SecurityException(
9454                        "Unable to find app for caller " + caller
9455                      + " (pid=" + Binder.getCallingPid()
9456                      + ") when publishing content providers");
9457            }
9458
9459            final long origId = Binder.clearCallingIdentity();
9460
9461            final int N = providers.size();
9462            for (int i=0; i<N; i++) {
9463                ContentProviderHolder src = providers.get(i);
9464                if (src == null || src.info == null || src.provider == null) {
9465                    continue;
9466                }
9467                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9468                if (DEBUG_MU)
9469                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9470                if (dst != null) {
9471                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9472                    mProviderMap.putProviderByClass(comp, dst);
9473                    String names[] = dst.info.authority.split(";");
9474                    for (int j = 0; j < names.length; j++) {
9475                        mProviderMap.putProviderByName(names[j], dst);
9476                    }
9477
9478                    int NL = mLaunchingProviders.size();
9479                    int j;
9480                    for (j=0; j<NL; j++) {
9481                        if (mLaunchingProviders.get(j) == dst) {
9482                            mLaunchingProviders.remove(j);
9483                            j--;
9484                            NL--;
9485                        }
9486                    }
9487                    synchronized (dst) {
9488                        dst.provider = src.provider;
9489                        dst.proc = r;
9490                        dst.notifyAll();
9491                    }
9492                    updateOomAdjLocked(r);
9493                }
9494            }
9495
9496            Binder.restoreCallingIdentity(origId);
9497        }
9498    }
9499
9500    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9501        ContentProviderConnection conn;
9502        try {
9503            conn = (ContentProviderConnection)connection;
9504        } catch (ClassCastException e) {
9505            String msg ="refContentProvider: " + connection
9506                    + " not a ContentProviderConnection";
9507            Slog.w(TAG, msg);
9508            throw new IllegalArgumentException(msg);
9509        }
9510        if (conn == null) {
9511            throw new NullPointerException("connection is null");
9512        }
9513
9514        synchronized (this) {
9515            if (stable > 0) {
9516                conn.numStableIncs += stable;
9517            }
9518            stable = conn.stableCount + stable;
9519            if (stable < 0) {
9520                throw new IllegalStateException("stableCount < 0: " + stable);
9521            }
9522
9523            if (unstable > 0) {
9524                conn.numUnstableIncs += unstable;
9525            }
9526            unstable = conn.unstableCount + unstable;
9527            if (unstable < 0) {
9528                throw new IllegalStateException("unstableCount < 0: " + unstable);
9529            }
9530
9531            if ((stable+unstable) <= 0) {
9532                throw new IllegalStateException("ref counts can't go to zero here: stable="
9533                        + stable + " unstable=" + unstable);
9534            }
9535            conn.stableCount = stable;
9536            conn.unstableCount = unstable;
9537            return !conn.dead;
9538        }
9539    }
9540
9541    public void unstableProviderDied(IBinder connection) {
9542        ContentProviderConnection conn;
9543        try {
9544            conn = (ContentProviderConnection)connection;
9545        } catch (ClassCastException e) {
9546            String msg ="refContentProvider: " + connection
9547                    + " not a ContentProviderConnection";
9548            Slog.w(TAG, msg);
9549            throw new IllegalArgumentException(msg);
9550        }
9551        if (conn == null) {
9552            throw new NullPointerException("connection is null");
9553        }
9554
9555        // Safely retrieve the content provider associated with the connection.
9556        IContentProvider provider;
9557        synchronized (this) {
9558            provider = conn.provider.provider;
9559        }
9560
9561        if (provider == null) {
9562            // Um, yeah, we're way ahead of you.
9563            return;
9564        }
9565
9566        // Make sure the caller is being honest with us.
9567        if (provider.asBinder().pingBinder()) {
9568            // Er, no, still looks good to us.
9569            synchronized (this) {
9570                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9571                        + " says " + conn + " died, but we don't agree");
9572                return;
9573            }
9574        }
9575
9576        // Well look at that!  It's dead!
9577        synchronized (this) {
9578            if (conn.provider.provider != provider) {
9579                // But something changed...  good enough.
9580                return;
9581            }
9582
9583            ProcessRecord proc = conn.provider.proc;
9584            if (proc == null || proc.thread == null) {
9585                // Seems like the process is already cleaned up.
9586                return;
9587            }
9588
9589            // As far as we're concerned, this is just like receiving a
9590            // death notification...  just a bit prematurely.
9591            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9592                    + ") early provider death");
9593            final long ident = Binder.clearCallingIdentity();
9594            try {
9595                appDiedLocked(proc);
9596            } finally {
9597                Binder.restoreCallingIdentity(ident);
9598            }
9599        }
9600    }
9601
9602    @Override
9603    public void appNotRespondingViaProvider(IBinder connection) {
9604        enforceCallingPermission(
9605                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9606
9607        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9608        if (conn == null) {
9609            Slog.w(TAG, "ContentProviderConnection is null");
9610            return;
9611        }
9612
9613        final ProcessRecord host = conn.provider.proc;
9614        if (host == null) {
9615            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9616            return;
9617        }
9618
9619        final long token = Binder.clearCallingIdentity();
9620        try {
9621            appNotResponding(host, null, null, false, "ContentProvider not responding");
9622        } finally {
9623            Binder.restoreCallingIdentity(token);
9624        }
9625    }
9626
9627    public final void installSystemProviders() {
9628        List<ProviderInfo> providers;
9629        synchronized (this) {
9630            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9631            providers = generateApplicationProvidersLocked(app);
9632            if (providers != null) {
9633                for (int i=providers.size()-1; i>=0; i--) {
9634                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9635                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9636                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9637                                + ": not system .apk");
9638                        providers.remove(i);
9639                    }
9640                }
9641            }
9642        }
9643        if (providers != null) {
9644            mSystemThread.installSystemProviders(providers);
9645        }
9646
9647        mCoreSettingsObserver = new CoreSettingsObserver(this);
9648
9649        //mUsageStatsService.monitorPackages();
9650    }
9651
9652    /**
9653     * Allows apps to retrieve the MIME type of a URI.
9654     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9655     * users, then it does not need permission to access the ContentProvider.
9656     * Either, it needs cross-user uri grants.
9657     *
9658     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9659     *
9660     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9661     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9662     */
9663    public String getProviderMimeType(Uri uri, int userId) {
9664        enforceNotIsolatedCaller("getProviderMimeType");
9665        final String name = uri.getAuthority();
9666        int callingUid = Binder.getCallingUid();
9667        int callingPid = Binder.getCallingPid();
9668        long ident = 0;
9669        boolean clearedIdentity = false;
9670        userId = unsafeConvertIncomingUser(userId);
9671        if (UserHandle.getUserId(callingUid) != userId) {
9672            if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9673                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9674                    || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9675                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9676                clearedIdentity = true;
9677                ident = Binder.clearCallingIdentity();
9678            }
9679        }
9680        ContentProviderHolder holder = null;
9681        try {
9682            holder = getContentProviderExternalUnchecked(name, null, userId);
9683            if (holder != null) {
9684                return holder.provider.getType(uri);
9685            }
9686        } catch (RemoteException e) {
9687            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9688            return null;
9689        } finally {
9690            // We need to clear the identity to call removeContentProviderExternalUnchecked
9691            if (!clearedIdentity) {
9692                ident = Binder.clearCallingIdentity();
9693            }
9694            try {
9695                if (holder != null) {
9696                    removeContentProviderExternalUnchecked(name, null, userId);
9697                }
9698            } finally {
9699                Binder.restoreCallingIdentity(ident);
9700            }
9701        }
9702
9703        return null;
9704    }
9705
9706    // =========================================================
9707    // GLOBAL MANAGEMENT
9708    // =========================================================
9709
9710    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9711            boolean isolated, int isolatedUid) {
9712        String proc = customProcess != null ? customProcess : info.processName;
9713        BatteryStatsImpl.Uid.Proc ps = null;
9714        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9715        int uid = info.uid;
9716        if (isolated) {
9717            if (isolatedUid == 0) {
9718                int userId = UserHandle.getUserId(uid);
9719                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9720                while (true) {
9721                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9722                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9723                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9724                    }
9725                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9726                    mNextIsolatedProcessUid++;
9727                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9728                        // No process for this uid, use it.
9729                        break;
9730                    }
9731                    stepsLeft--;
9732                    if (stepsLeft <= 0) {
9733                        return null;
9734                    }
9735                }
9736            } else {
9737                // Special case for startIsolatedProcess (internal only), where
9738                // the uid of the isolated process is specified by the caller.
9739                uid = isolatedUid;
9740            }
9741        }
9742        return new ProcessRecord(stats, info, proc, uid);
9743    }
9744
9745    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9746            String abiOverride) {
9747        ProcessRecord app;
9748        if (!isolated) {
9749            app = getProcessRecordLocked(info.processName, info.uid, true);
9750        } else {
9751            app = null;
9752        }
9753
9754        if (app == null) {
9755            app = newProcessRecordLocked(info, null, isolated, 0);
9756            mProcessNames.put(info.processName, app.uid, app);
9757            if (isolated) {
9758                mIsolatedProcesses.put(app.uid, app);
9759            }
9760            updateLruProcessLocked(app, false, null);
9761            updateOomAdjLocked();
9762        }
9763
9764        // This package really, really can not be stopped.
9765        try {
9766            AppGlobals.getPackageManager().setPackageStoppedState(
9767                    info.packageName, false, UserHandle.getUserId(app.uid));
9768        } catch (RemoteException e) {
9769        } catch (IllegalArgumentException e) {
9770            Slog.w(TAG, "Failed trying to unstop package "
9771                    + info.packageName + ": " + e);
9772        }
9773
9774        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9775                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9776            app.persistent = true;
9777            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9778        }
9779        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9780            mPersistentStartingProcesses.add(app);
9781            startProcessLocked(app, "added application", app.processName, abiOverride,
9782                    null /* entryPoint */, null /* entryPointArgs */);
9783        }
9784
9785        return app;
9786    }
9787
9788    public void unhandledBack() {
9789        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9790                "unhandledBack()");
9791
9792        synchronized(this) {
9793            final long origId = Binder.clearCallingIdentity();
9794            try {
9795                getFocusedStack().unhandledBackLocked();
9796            } finally {
9797                Binder.restoreCallingIdentity(origId);
9798            }
9799        }
9800    }
9801
9802    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9803        enforceNotIsolatedCaller("openContentUri");
9804        final int userId = UserHandle.getCallingUserId();
9805        String name = uri.getAuthority();
9806        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9807        ParcelFileDescriptor pfd = null;
9808        if (cph != null) {
9809            // We record the binder invoker's uid in thread-local storage before
9810            // going to the content provider to open the file.  Later, in the code
9811            // that handles all permissions checks, we look for this uid and use
9812            // that rather than the Activity Manager's own uid.  The effect is that
9813            // we do the check against the caller's permissions even though it looks
9814            // to the content provider like the Activity Manager itself is making
9815            // the request.
9816            sCallerIdentity.set(new Identity(
9817                    Binder.getCallingPid(), Binder.getCallingUid()));
9818            try {
9819                pfd = cph.provider.openFile(null, uri, "r", null);
9820            } catch (FileNotFoundException e) {
9821                // do nothing; pfd will be returned null
9822            } finally {
9823                // Ensure that whatever happens, we clean up the identity state
9824                sCallerIdentity.remove();
9825            }
9826
9827            // We've got the fd now, so we're done with the provider.
9828            removeContentProviderExternalUnchecked(name, null, userId);
9829        } else {
9830            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9831        }
9832        return pfd;
9833    }
9834
9835    // Actually is sleeping or shutting down or whatever else in the future
9836    // is an inactive state.
9837    public boolean isSleepingOrShuttingDown() {
9838        return mSleeping || mShuttingDown;
9839    }
9840
9841    public boolean isSleeping() {
9842        return mSleeping;
9843    }
9844
9845    void goingToSleep() {
9846        synchronized(this) {
9847            mWentToSleep = true;
9848            updateEventDispatchingLocked();
9849            goToSleepIfNeededLocked();
9850        }
9851    }
9852
9853    void finishRunningVoiceLocked() {
9854        if (mRunningVoice) {
9855            mRunningVoice = false;
9856            goToSleepIfNeededLocked();
9857        }
9858    }
9859
9860    void goToSleepIfNeededLocked() {
9861        if (mWentToSleep && !mRunningVoice) {
9862            if (!mSleeping) {
9863                mSleeping = true;
9864                mStackSupervisor.goingToSleepLocked();
9865
9866                // Initialize the wake times of all processes.
9867                checkExcessivePowerUsageLocked(false);
9868                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9869                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9870                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9871            }
9872        }
9873    }
9874
9875    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9876        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9877            // Never persist the home stack.
9878            return;
9879        }
9880        mTaskPersister.wakeup(task, flush);
9881    }
9882
9883    @Override
9884    public boolean shutdown(int timeout) {
9885        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9886                != PackageManager.PERMISSION_GRANTED) {
9887            throw new SecurityException("Requires permission "
9888                    + android.Manifest.permission.SHUTDOWN);
9889        }
9890
9891        boolean timedout = false;
9892
9893        synchronized(this) {
9894            mShuttingDown = true;
9895            updateEventDispatchingLocked();
9896            timedout = mStackSupervisor.shutdownLocked(timeout);
9897        }
9898
9899        mAppOpsService.shutdown();
9900        if (mUsageStatsService != null) {
9901            mUsageStatsService.prepareShutdown();
9902        }
9903        mBatteryStatsService.shutdown();
9904        synchronized (this) {
9905            mProcessStats.shutdownLocked();
9906        }
9907        notifyTaskPersisterLocked(null, true);
9908
9909        return timedout;
9910    }
9911
9912    public final void activitySlept(IBinder token) {
9913        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9914
9915        final long origId = Binder.clearCallingIdentity();
9916
9917        synchronized (this) {
9918            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9919            if (r != null) {
9920                mStackSupervisor.activitySleptLocked(r);
9921            }
9922        }
9923
9924        Binder.restoreCallingIdentity(origId);
9925    }
9926
9927    void logLockScreen(String msg) {
9928        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9929                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9930                mWentToSleep + " mSleeping=" + mSleeping);
9931    }
9932
9933    private void comeOutOfSleepIfNeededLocked() {
9934        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9935            if (mSleeping) {
9936                mSleeping = false;
9937                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9938            }
9939        }
9940    }
9941
9942    void wakingUp() {
9943        synchronized(this) {
9944            mWentToSleep = false;
9945            updateEventDispatchingLocked();
9946            comeOutOfSleepIfNeededLocked();
9947        }
9948    }
9949
9950    void startRunningVoiceLocked() {
9951        if (!mRunningVoice) {
9952            mRunningVoice = true;
9953            comeOutOfSleepIfNeededLocked();
9954        }
9955    }
9956
9957    private void updateEventDispatchingLocked() {
9958        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
9959    }
9960
9961    public void setLockScreenShown(boolean shown) {
9962        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9963                != PackageManager.PERMISSION_GRANTED) {
9964            throw new SecurityException("Requires permission "
9965                    + android.Manifest.permission.DEVICE_POWER);
9966        }
9967
9968        synchronized(this) {
9969            long ident = Binder.clearCallingIdentity();
9970            try {
9971                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9972                mLockScreenShown = shown;
9973                comeOutOfSleepIfNeededLocked();
9974            } finally {
9975                Binder.restoreCallingIdentity(ident);
9976            }
9977        }
9978    }
9979
9980    @Override
9981    public void stopAppSwitches() {
9982        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9983                != PackageManager.PERMISSION_GRANTED) {
9984            throw new SecurityException("Requires permission "
9985                    + android.Manifest.permission.STOP_APP_SWITCHES);
9986        }
9987
9988        synchronized(this) {
9989            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9990                    + APP_SWITCH_DELAY_TIME;
9991            mDidAppSwitch = false;
9992            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9993            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9994            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9995        }
9996    }
9997
9998    public void resumeAppSwitches() {
9999        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10000                != PackageManager.PERMISSION_GRANTED) {
10001            throw new SecurityException("Requires permission "
10002                    + android.Manifest.permission.STOP_APP_SWITCHES);
10003        }
10004
10005        synchronized(this) {
10006            // Note that we don't execute any pending app switches... we will
10007            // let those wait until either the timeout, or the next start
10008            // activity request.
10009            mAppSwitchesAllowedTime = 0;
10010        }
10011    }
10012
10013    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
10014            String name) {
10015        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10016            return true;
10017        }
10018
10019        final int perm = checkComponentPermission(
10020                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10021                callingUid, -1, true);
10022        if (perm == PackageManager.PERMISSION_GRANTED) {
10023            return true;
10024        }
10025
10026        Slog.w(TAG, name + " request from " + callingUid + " stopped");
10027        return false;
10028    }
10029
10030    public void setDebugApp(String packageName, boolean waitForDebugger,
10031            boolean persistent) {
10032        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10033                "setDebugApp()");
10034
10035        long ident = Binder.clearCallingIdentity();
10036        try {
10037            // Note that this is not really thread safe if there are multiple
10038            // callers into it at the same time, but that's not a situation we
10039            // care about.
10040            if (persistent) {
10041                final ContentResolver resolver = mContext.getContentResolver();
10042                Settings.Global.putString(
10043                    resolver, Settings.Global.DEBUG_APP,
10044                    packageName);
10045                Settings.Global.putInt(
10046                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10047                    waitForDebugger ? 1 : 0);
10048            }
10049
10050            synchronized (this) {
10051                if (!persistent) {
10052                    mOrigDebugApp = mDebugApp;
10053                    mOrigWaitForDebugger = mWaitForDebugger;
10054                }
10055                mDebugApp = packageName;
10056                mWaitForDebugger = waitForDebugger;
10057                mDebugTransient = !persistent;
10058                if (packageName != null) {
10059                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10060                            false, UserHandle.USER_ALL, "set debug app");
10061                }
10062            }
10063        } finally {
10064            Binder.restoreCallingIdentity(ident);
10065        }
10066    }
10067
10068    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10069        synchronized (this) {
10070            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10071            if (!isDebuggable) {
10072                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10073                    throw new SecurityException("Process not debuggable: " + app.packageName);
10074                }
10075            }
10076
10077            mOpenGlTraceApp = processName;
10078        }
10079    }
10080
10081    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10082        synchronized (this) {
10083            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10084            if (!isDebuggable) {
10085                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10086                    throw new SecurityException("Process not debuggable: " + app.packageName);
10087                }
10088            }
10089            mProfileApp = processName;
10090            mProfileFile = profilerInfo.profileFile;
10091            if (mProfileFd != null) {
10092                try {
10093                    mProfileFd.close();
10094                } catch (IOException e) {
10095                }
10096                mProfileFd = null;
10097            }
10098            mProfileFd = profilerInfo.profileFd;
10099            mSamplingInterval = profilerInfo.samplingInterval;
10100            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10101            mProfileType = 0;
10102        }
10103    }
10104
10105    @Override
10106    public void setAlwaysFinish(boolean enabled) {
10107        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10108                "setAlwaysFinish()");
10109
10110        Settings.Global.putInt(
10111                mContext.getContentResolver(),
10112                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10113
10114        synchronized (this) {
10115            mAlwaysFinishActivities = enabled;
10116        }
10117    }
10118
10119    @Override
10120    public void setActivityController(IActivityController controller) {
10121        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10122                "setActivityController()");
10123        synchronized (this) {
10124            mController = controller;
10125            Watchdog.getInstance().setActivityController(controller);
10126        }
10127    }
10128
10129    @Override
10130    public void setUserIsMonkey(boolean userIsMonkey) {
10131        synchronized (this) {
10132            synchronized (mPidsSelfLocked) {
10133                final int callingPid = Binder.getCallingPid();
10134                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10135                if (precessRecord == null) {
10136                    throw new SecurityException("Unknown process: " + callingPid);
10137                }
10138                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10139                    throw new SecurityException("Only an instrumentation process "
10140                            + "with a UiAutomation can call setUserIsMonkey");
10141                }
10142            }
10143            mUserIsMonkey = userIsMonkey;
10144        }
10145    }
10146
10147    @Override
10148    public boolean isUserAMonkey() {
10149        synchronized (this) {
10150            // If there is a controller also implies the user is a monkey.
10151            return (mUserIsMonkey || mController != null);
10152        }
10153    }
10154
10155    public void requestBugReport() {
10156        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10157        SystemProperties.set("ctl.start", "bugreport");
10158    }
10159
10160    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10161        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10162    }
10163
10164    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10165        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10166            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10167        }
10168        return KEY_DISPATCHING_TIMEOUT;
10169    }
10170
10171    @Override
10172    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10173        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10174                != PackageManager.PERMISSION_GRANTED) {
10175            throw new SecurityException("Requires permission "
10176                    + android.Manifest.permission.FILTER_EVENTS);
10177        }
10178        ProcessRecord proc;
10179        long timeout;
10180        synchronized (this) {
10181            synchronized (mPidsSelfLocked) {
10182                proc = mPidsSelfLocked.get(pid);
10183            }
10184            timeout = getInputDispatchingTimeoutLocked(proc);
10185        }
10186
10187        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10188            return -1;
10189        }
10190
10191        return timeout;
10192    }
10193
10194    /**
10195     * Handle input dispatching timeouts.
10196     * Returns whether input dispatching should be aborted or not.
10197     */
10198    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10199            final ActivityRecord activity, final ActivityRecord parent,
10200            final boolean aboveSystem, String reason) {
10201        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10202                != PackageManager.PERMISSION_GRANTED) {
10203            throw new SecurityException("Requires permission "
10204                    + android.Manifest.permission.FILTER_EVENTS);
10205        }
10206
10207        final String annotation;
10208        if (reason == null) {
10209            annotation = "Input dispatching timed out";
10210        } else {
10211            annotation = "Input dispatching timed out (" + reason + ")";
10212        }
10213
10214        if (proc != null) {
10215            synchronized (this) {
10216                if (proc.debugging) {
10217                    return false;
10218                }
10219
10220                if (mDidDexOpt) {
10221                    // Give more time since we were dexopting.
10222                    mDidDexOpt = false;
10223                    return false;
10224                }
10225
10226                if (proc.instrumentationClass != null) {
10227                    Bundle info = new Bundle();
10228                    info.putString("shortMsg", "keyDispatchingTimedOut");
10229                    info.putString("longMsg", annotation);
10230                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10231                    return true;
10232                }
10233            }
10234            mHandler.post(new Runnable() {
10235                @Override
10236                public void run() {
10237                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10238                }
10239            });
10240        }
10241
10242        return true;
10243    }
10244
10245    public Bundle getAssistContextExtras(int requestType) {
10246        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10247                "getAssistContextExtras()");
10248        PendingAssistExtras pae;
10249        Bundle extras = new Bundle();
10250        synchronized (this) {
10251            ActivityRecord activity = getFocusedStack().mResumedActivity;
10252            if (activity == null) {
10253                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10254                return null;
10255            }
10256            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10257            if (activity.app == null || activity.app.thread == null) {
10258                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10259                return extras;
10260            }
10261            if (activity.app.pid == Binder.getCallingPid()) {
10262                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10263                return extras;
10264            }
10265            pae = new PendingAssistExtras(activity);
10266            try {
10267                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10268                        requestType);
10269                mPendingAssistExtras.add(pae);
10270                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10271            } catch (RemoteException e) {
10272                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10273                return extras;
10274            }
10275        }
10276        synchronized (pae) {
10277            while (!pae.haveResult) {
10278                try {
10279                    pae.wait();
10280                } catch (InterruptedException e) {
10281                }
10282            }
10283            if (pae.result != null) {
10284                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10285            }
10286        }
10287        synchronized (this) {
10288            mPendingAssistExtras.remove(pae);
10289            mHandler.removeCallbacks(pae);
10290        }
10291        return extras;
10292    }
10293
10294    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10295        PendingAssistExtras pae = (PendingAssistExtras)token;
10296        synchronized (pae) {
10297            pae.result = extras;
10298            pae.haveResult = true;
10299            pae.notifyAll();
10300        }
10301    }
10302
10303    public void registerProcessObserver(IProcessObserver observer) {
10304        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10305                "registerProcessObserver()");
10306        synchronized (this) {
10307            mProcessObservers.register(observer);
10308        }
10309    }
10310
10311    @Override
10312    public void unregisterProcessObserver(IProcessObserver observer) {
10313        synchronized (this) {
10314            mProcessObservers.unregister(observer);
10315        }
10316    }
10317
10318    @Override
10319    public boolean convertFromTranslucent(IBinder token) {
10320        final long origId = Binder.clearCallingIdentity();
10321        try {
10322            synchronized (this) {
10323                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10324                if (r == null) {
10325                    return false;
10326                }
10327                final boolean translucentChanged = r.changeWindowTranslucency(true);
10328                if (translucentChanged) {
10329                    r.task.stack.releaseBackgroundResources();
10330                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10331                }
10332                mWindowManager.setAppFullscreen(token, true);
10333                return translucentChanged;
10334            }
10335        } finally {
10336            Binder.restoreCallingIdentity(origId);
10337        }
10338    }
10339
10340    @Override
10341    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10342        final long origId = Binder.clearCallingIdentity();
10343        try {
10344            synchronized (this) {
10345                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10346                if (r == null) {
10347                    return false;
10348                }
10349                int index = r.task.mActivities.lastIndexOf(r);
10350                if (index > 0) {
10351                    ActivityRecord under = r.task.mActivities.get(index - 1);
10352                    under.returningOptions = options;
10353                }
10354                final boolean translucentChanged = r.changeWindowTranslucency(false);
10355                if (translucentChanged) {
10356                    r.task.stack.convertToTranslucent(r);
10357                }
10358                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10359                mWindowManager.setAppFullscreen(token, false);
10360                return translucentChanged;
10361            }
10362        } finally {
10363            Binder.restoreCallingIdentity(origId);
10364        }
10365    }
10366
10367    @Override
10368    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10369        final long origId = Binder.clearCallingIdentity();
10370        try {
10371            synchronized (this) {
10372                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10373                if (r != null) {
10374                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10375                }
10376            }
10377            return false;
10378        } finally {
10379            Binder.restoreCallingIdentity(origId);
10380        }
10381    }
10382
10383    @Override
10384    public boolean isBackgroundVisibleBehind(IBinder token) {
10385        final long origId = Binder.clearCallingIdentity();
10386        try {
10387            synchronized (this) {
10388                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10389                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10390                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10391                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10392                return visible;
10393            }
10394        } finally {
10395            Binder.restoreCallingIdentity(origId);
10396        }
10397    }
10398
10399    @Override
10400    public ActivityOptions getActivityOptions(IBinder token) {
10401        final long origId = Binder.clearCallingIdentity();
10402        try {
10403            synchronized (this) {
10404                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10405                if (r != null) {
10406                    final ActivityOptions activityOptions = r.pendingOptions;
10407                    r.pendingOptions = null;
10408                    return activityOptions;
10409                }
10410                return null;
10411            }
10412        } finally {
10413            Binder.restoreCallingIdentity(origId);
10414        }
10415    }
10416
10417    @Override
10418    public void setImmersive(IBinder token, boolean immersive) {
10419        synchronized(this) {
10420            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10421            if (r == null) {
10422                throw new IllegalArgumentException();
10423            }
10424            r.immersive = immersive;
10425
10426            // update associated state if we're frontmost
10427            if (r == mFocusedActivity) {
10428                if (DEBUG_IMMERSIVE) {
10429                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10430                }
10431                applyUpdateLockStateLocked(r);
10432            }
10433        }
10434    }
10435
10436    @Override
10437    public boolean isImmersive(IBinder token) {
10438        synchronized (this) {
10439            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10440            if (r == null) {
10441                throw new IllegalArgumentException();
10442            }
10443            return r.immersive;
10444        }
10445    }
10446
10447    public boolean isTopActivityImmersive() {
10448        enforceNotIsolatedCaller("startActivity");
10449        synchronized (this) {
10450            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10451            return (r != null) ? r.immersive : false;
10452        }
10453    }
10454
10455    @Override
10456    public boolean isTopOfTask(IBinder token) {
10457        synchronized (this) {
10458            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10459            if (r == null) {
10460                throw new IllegalArgumentException();
10461            }
10462            return r.task.getTopActivity() == r;
10463        }
10464    }
10465
10466    public final void enterSafeMode() {
10467        synchronized(this) {
10468            // It only makes sense to do this before the system is ready
10469            // and started launching other packages.
10470            if (!mSystemReady) {
10471                try {
10472                    AppGlobals.getPackageManager().enterSafeMode();
10473                } catch (RemoteException e) {
10474                }
10475            }
10476
10477            mSafeMode = true;
10478        }
10479    }
10480
10481    public final void showSafeModeOverlay() {
10482        View v = LayoutInflater.from(mContext).inflate(
10483                com.android.internal.R.layout.safe_mode, null);
10484        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10485        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10486        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10487        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10488        lp.gravity = Gravity.BOTTOM | Gravity.START;
10489        lp.format = v.getBackground().getOpacity();
10490        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10491                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10492        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10493        ((WindowManager)mContext.getSystemService(
10494                Context.WINDOW_SERVICE)).addView(v, lp);
10495    }
10496
10497    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10498        if (!(sender instanceof PendingIntentRecord)) {
10499            return;
10500        }
10501        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10502        synchronized (stats) {
10503            if (mBatteryStatsService.isOnBattery()) {
10504                mBatteryStatsService.enforceCallingPermission();
10505                PendingIntentRecord rec = (PendingIntentRecord)sender;
10506                int MY_UID = Binder.getCallingUid();
10507                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10508                BatteryStatsImpl.Uid.Pkg pkg =
10509                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10510                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10511                pkg.incWakeupsLocked();
10512            }
10513        }
10514    }
10515
10516    public boolean killPids(int[] pids, String pReason, boolean secure) {
10517        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10518            throw new SecurityException("killPids only available to the system");
10519        }
10520        String reason = (pReason == null) ? "Unknown" : pReason;
10521        // XXX Note: don't acquire main activity lock here, because the window
10522        // manager calls in with its locks held.
10523
10524        boolean killed = false;
10525        synchronized (mPidsSelfLocked) {
10526            int[] types = new int[pids.length];
10527            int worstType = 0;
10528            for (int i=0; i<pids.length; i++) {
10529                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10530                if (proc != null) {
10531                    int type = proc.setAdj;
10532                    types[i] = type;
10533                    if (type > worstType) {
10534                        worstType = type;
10535                    }
10536                }
10537            }
10538
10539            // If the worst oom_adj is somewhere in the cached proc LRU range,
10540            // then constrain it so we will kill all cached procs.
10541            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10542                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10543                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10544            }
10545
10546            // If this is not a secure call, don't let it kill processes that
10547            // are important.
10548            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10549                worstType = ProcessList.SERVICE_ADJ;
10550            }
10551
10552            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10553            for (int i=0; i<pids.length; i++) {
10554                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10555                if (proc == null) {
10556                    continue;
10557                }
10558                int adj = proc.setAdj;
10559                if (adj >= worstType && !proc.killedByAm) {
10560                    proc.kill(reason, true);
10561                    killed = true;
10562                }
10563            }
10564        }
10565        return killed;
10566    }
10567
10568    @Override
10569    public void killUid(int uid, String reason) {
10570        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10571            throw new SecurityException("killUid only available to the system");
10572        }
10573        synchronized (this) {
10574            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10575                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10576                    reason != null ? reason : "kill uid");
10577        }
10578    }
10579
10580    @Override
10581    public boolean killProcessesBelowForeground(String reason) {
10582        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10583            throw new SecurityException("killProcessesBelowForeground() only available to system");
10584        }
10585
10586        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10587    }
10588
10589    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10590        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10591            throw new SecurityException("killProcessesBelowAdj() only available to system");
10592        }
10593
10594        boolean killed = false;
10595        synchronized (mPidsSelfLocked) {
10596            final int size = mPidsSelfLocked.size();
10597            for (int i = 0; i < size; i++) {
10598                final int pid = mPidsSelfLocked.keyAt(i);
10599                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10600                if (proc == null) continue;
10601
10602                final int adj = proc.setAdj;
10603                if (adj > belowAdj && !proc.killedByAm) {
10604                    proc.kill(reason, true);
10605                    killed = true;
10606                }
10607            }
10608        }
10609        return killed;
10610    }
10611
10612    @Override
10613    public void hang(final IBinder who, boolean allowRestart) {
10614        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10615                != PackageManager.PERMISSION_GRANTED) {
10616            throw new SecurityException("Requires permission "
10617                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10618        }
10619
10620        final IBinder.DeathRecipient death = new DeathRecipient() {
10621            @Override
10622            public void binderDied() {
10623                synchronized (this) {
10624                    notifyAll();
10625                }
10626            }
10627        };
10628
10629        try {
10630            who.linkToDeath(death, 0);
10631        } catch (RemoteException e) {
10632            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10633            return;
10634        }
10635
10636        synchronized (this) {
10637            Watchdog.getInstance().setAllowRestart(allowRestart);
10638            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10639            synchronized (death) {
10640                while (who.isBinderAlive()) {
10641                    try {
10642                        death.wait();
10643                    } catch (InterruptedException e) {
10644                    }
10645                }
10646            }
10647            Watchdog.getInstance().setAllowRestart(true);
10648        }
10649    }
10650
10651    @Override
10652    public void restart() {
10653        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10654                != PackageManager.PERMISSION_GRANTED) {
10655            throw new SecurityException("Requires permission "
10656                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10657        }
10658
10659        Log.i(TAG, "Sending shutdown broadcast...");
10660
10661        BroadcastReceiver br = new BroadcastReceiver() {
10662            @Override public void onReceive(Context context, Intent intent) {
10663                // Now the broadcast is done, finish up the low-level shutdown.
10664                Log.i(TAG, "Shutting down activity manager...");
10665                shutdown(10000);
10666                Log.i(TAG, "Shutdown complete, restarting!");
10667                Process.killProcess(Process.myPid());
10668                System.exit(10);
10669            }
10670        };
10671
10672        // First send the high-level shut down broadcast.
10673        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10674        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10675        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10676        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10677        mContext.sendOrderedBroadcastAsUser(intent,
10678                UserHandle.ALL, null, br, mHandler, 0, null, null);
10679        */
10680        br.onReceive(mContext, intent);
10681    }
10682
10683    private long getLowRamTimeSinceIdle(long now) {
10684        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10685    }
10686
10687    @Override
10688    public void performIdleMaintenance() {
10689        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10690                != PackageManager.PERMISSION_GRANTED) {
10691            throw new SecurityException("Requires permission "
10692                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10693        }
10694
10695        synchronized (this) {
10696            final long now = SystemClock.uptimeMillis();
10697            final long timeSinceLastIdle = now - mLastIdleTime;
10698            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10699            mLastIdleTime = now;
10700            mLowRamTimeSinceLastIdle = 0;
10701            if (mLowRamStartTime != 0) {
10702                mLowRamStartTime = now;
10703            }
10704
10705            StringBuilder sb = new StringBuilder(128);
10706            sb.append("Idle maintenance over ");
10707            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10708            sb.append(" low RAM for ");
10709            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10710            Slog.i(TAG, sb.toString());
10711
10712            // If at least 1/3 of our time since the last idle period has been spent
10713            // with RAM low, then we want to kill processes.
10714            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10715
10716            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10717                ProcessRecord proc = mLruProcesses.get(i);
10718                if (proc.notCachedSinceIdle) {
10719                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10720                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10721                        if (doKilling && proc.initialIdlePss != 0
10722                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10723                            proc.kill("idle maint (pss " + proc.lastPss
10724                                    + " from " + proc.initialIdlePss + ")", true);
10725                        }
10726                    }
10727                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10728                    proc.notCachedSinceIdle = true;
10729                    proc.initialIdlePss = 0;
10730                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10731                            isSleeping(), now);
10732                }
10733            }
10734
10735            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10736            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10737        }
10738    }
10739
10740    private void retrieveSettings() {
10741        final ContentResolver resolver = mContext.getContentResolver();
10742        String debugApp = Settings.Global.getString(
10743            resolver, Settings.Global.DEBUG_APP);
10744        boolean waitForDebugger = Settings.Global.getInt(
10745            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10746        boolean alwaysFinishActivities = Settings.Global.getInt(
10747            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10748        boolean forceRtl = Settings.Global.getInt(
10749                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10750        // Transfer any global setting for forcing RTL layout, into a System Property
10751        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10752
10753        Configuration configuration = new Configuration();
10754        Settings.System.getConfiguration(resolver, configuration);
10755        if (forceRtl) {
10756            // This will take care of setting the correct layout direction flags
10757            configuration.setLayoutDirection(configuration.locale);
10758        }
10759
10760        synchronized (this) {
10761            mDebugApp = mOrigDebugApp = debugApp;
10762            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10763            mAlwaysFinishActivities = alwaysFinishActivities;
10764            // This happens before any activities are started, so we can
10765            // change mConfiguration in-place.
10766            updateConfigurationLocked(configuration, null, false, true);
10767            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10768        }
10769    }
10770
10771    /** Loads resources after the current configuration has been set. */
10772    private void loadResourcesOnSystemReady() {
10773        final Resources res = mContext.getResources();
10774        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10775        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10776        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10777    }
10778
10779    public boolean testIsSystemReady() {
10780        // no need to synchronize(this) just to read & return the value
10781        return mSystemReady;
10782    }
10783
10784    private static File getCalledPreBootReceiversFile() {
10785        File dataDir = Environment.getDataDirectory();
10786        File systemDir = new File(dataDir, "system");
10787        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10788        return fname;
10789    }
10790
10791    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10792        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10793        File file = getCalledPreBootReceiversFile();
10794        FileInputStream fis = null;
10795        try {
10796            fis = new FileInputStream(file);
10797            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10798            int fvers = dis.readInt();
10799            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10800                String vers = dis.readUTF();
10801                String codename = dis.readUTF();
10802                String build = dis.readUTF();
10803                if (android.os.Build.VERSION.RELEASE.equals(vers)
10804                        && android.os.Build.VERSION.CODENAME.equals(codename)
10805                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10806                    int num = dis.readInt();
10807                    while (num > 0) {
10808                        num--;
10809                        String pkg = dis.readUTF();
10810                        String cls = dis.readUTF();
10811                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10812                    }
10813                }
10814            }
10815        } catch (FileNotFoundException e) {
10816        } catch (IOException e) {
10817            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10818        } finally {
10819            if (fis != null) {
10820                try {
10821                    fis.close();
10822                } catch (IOException e) {
10823                }
10824            }
10825        }
10826        return lastDoneReceivers;
10827    }
10828
10829    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10830        File file = getCalledPreBootReceiversFile();
10831        FileOutputStream fos = null;
10832        DataOutputStream dos = null;
10833        try {
10834            fos = new FileOutputStream(file);
10835            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10836            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10837            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10838            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10839            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10840            dos.writeInt(list.size());
10841            for (int i=0; i<list.size(); i++) {
10842                dos.writeUTF(list.get(i).getPackageName());
10843                dos.writeUTF(list.get(i).getClassName());
10844            }
10845        } catch (IOException e) {
10846            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10847            file.delete();
10848        } finally {
10849            FileUtils.sync(fos);
10850            if (dos != null) {
10851                try {
10852                    dos.close();
10853                } catch (IOException e) {
10854                    // TODO Auto-generated catch block
10855                    e.printStackTrace();
10856                }
10857            }
10858        }
10859    }
10860
10861    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10862            ArrayList<ComponentName> doneReceivers, int userId) {
10863        boolean waitingUpdate = false;
10864        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10865        List<ResolveInfo> ris = null;
10866        try {
10867            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10868                    intent, null, 0, userId);
10869        } catch (RemoteException e) {
10870        }
10871        if (ris != null) {
10872            for (int i=ris.size()-1; i>=0; i--) {
10873                if ((ris.get(i).activityInfo.applicationInfo.flags
10874                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10875                    ris.remove(i);
10876                }
10877            }
10878            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10879
10880            // For User 0, load the version number. When delivering to a new user, deliver
10881            // to all receivers.
10882            if (userId == UserHandle.USER_OWNER) {
10883                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10884                for (int i=0; i<ris.size(); i++) {
10885                    ActivityInfo ai = ris.get(i).activityInfo;
10886                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10887                    if (lastDoneReceivers.contains(comp)) {
10888                        // We already did the pre boot receiver for this app with the current
10889                        // platform version, so don't do it again...
10890                        ris.remove(i);
10891                        i--;
10892                        // ...however, do keep it as one that has been done, so we don't
10893                        // forget about it when rewriting the file of last done receivers.
10894                        doneReceivers.add(comp);
10895                    }
10896                }
10897            }
10898
10899            // If primary user, send broadcast to all available users, else just to userId
10900            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10901                    : new int[] { userId };
10902            for (int i = 0; i < ris.size(); i++) {
10903                ActivityInfo ai = ris.get(i).activityInfo;
10904                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10905                doneReceivers.add(comp);
10906                intent.setComponent(comp);
10907                for (int j=0; j<users.length; j++) {
10908                    IIntentReceiver finisher = null;
10909                    // On last receiver and user, set up a completion callback
10910                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10911                        finisher = new IIntentReceiver.Stub() {
10912                            public void performReceive(Intent intent, int resultCode,
10913                                    String data, Bundle extras, boolean ordered,
10914                                    boolean sticky, int sendingUser) {
10915                                // The raw IIntentReceiver interface is called
10916                                // with the AM lock held, so redispatch to
10917                                // execute our code without the lock.
10918                                mHandler.post(onFinishCallback);
10919                            }
10920                        };
10921                    }
10922                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10923                            + " for user " + users[j]);
10924                    broadcastIntentLocked(null, null, intent, null, finisher,
10925                            0, null, null, null, AppOpsManager.OP_NONE,
10926                            true, false, MY_PID, Process.SYSTEM_UID,
10927                            users[j]);
10928                    if (finisher != null) {
10929                        waitingUpdate = true;
10930                    }
10931                }
10932            }
10933        }
10934
10935        return waitingUpdate;
10936    }
10937
10938    public void systemReady(final Runnable goingCallback) {
10939        synchronized(this) {
10940            if (mSystemReady) {
10941                // If we're done calling all the receivers, run the next "boot phase" passed in
10942                // by the SystemServer
10943                if (goingCallback != null) {
10944                    goingCallback.run();
10945                }
10946                return;
10947            }
10948
10949            // Make sure we have the current profile info, since it is needed for
10950            // security checks.
10951            updateCurrentProfileIdsLocked();
10952
10953            if (mRecentTasks == null) {
10954                mRecentTasks = mTaskPersister.restoreTasksLocked();
10955                if (!mRecentTasks.isEmpty()) {
10956                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10957                }
10958                cleanupRecentTasksLocked(UserHandle.USER_ALL);
10959                mTaskPersister.startPersisting();
10960            }
10961
10962            // Check to see if there are any update receivers to run.
10963            if (!mDidUpdate) {
10964                if (mWaitingUpdate) {
10965                    return;
10966                }
10967                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10968                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10969                    public void run() {
10970                        synchronized (ActivityManagerService.this) {
10971                            mDidUpdate = true;
10972                        }
10973                        writeLastDonePreBootReceivers(doneReceivers);
10974                        showBootMessage(mContext.getText(
10975                                R.string.android_upgrading_complete),
10976                                false);
10977                        systemReady(goingCallback);
10978                    }
10979                }, doneReceivers, UserHandle.USER_OWNER);
10980
10981                if (mWaitingUpdate) {
10982                    return;
10983                }
10984                mDidUpdate = true;
10985            }
10986
10987            mAppOpsService.systemReady();
10988            mSystemReady = true;
10989        }
10990
10991        ArrayList<ProcessRecord> procsToKill = null;
10992        synchronized(mPidsSelfLocked) {
10993            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10994                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10995                if (!isAllowedWhileBooting(proc.info)){
10996                    if (procsToKill == null) {
10997                        procsToKill = new ArrayList<ProcessRecord>();
10998                    }
10999                    procsToKill.add(proc);
11000                }
11001            }
11002        }
11003
11004        synchronized(this) {
11005            if (procsToKill != null) {
11006                for (int i=procsToKill.size()-1; i>=0; i--) {
11007                    ProcessRecord proc = procsToKill.get(i);
11008                    Slog.i(TAG, "Removing system update proc: " + proc);
11009                    removeProcessLocked(proc, true, false, "system update done");
11010                }
11011            }
11012
11013            // Now that we have cleaned up any update processes, we
11014            // are ready to start launching real processes and know that
11015            // we won't trample on them any more.
11016            mProcessesReady = true;
11017        }
11018
11019        Slog.i(TAG, "System now ready");
11020        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11021            SystemClock.uptimeMillis());
11022
11023        synchronized(this) {
11024            // Make sure we have no pre-ready processes sitting around.
11025
11026            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11027                ResolveInfo ri = mContext.getPackageManager()
11028                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11029                                STOCK_PM_FLAGS);
11030                CharSequence errorMsg = null;
11031                if (ri != null) {
11032                    ActivityInfo ai = ri.activityInfo;
11033                    ApplicationInfo app = ai.applicationInfo;
11034                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11035                        mTopAction = Intent.ACTION_FACTORY_TEST;
11036                        mTopData = null;
11037                        mTopComponent = new ComponentName(app.packageName,
11038                                ai.name);
11039                    } else {
11040                        errorMsg = mContext.getResources().getText(
11041                                com.android.internal.R.string.factorytest_not_system);
11042                    }
11043                } else {
11044                    errorMsg = mContext.getResources().getText(
11045                            com.android.internal.R.string.factorytest_no_action);
11046                }
11047                if (errorMsg != null) {
11048                    mTopAction = null;
11049                    mTopData = null;
11050                    mTopComponent = null;
11051                    Message msg = Message.obtain();
11052                    msg.what = SHOW_FACTORY_ERROR_MSG;
11053                    msg.getData().putCharSequence("msg", errorMsg);
11054                    mHandler.sendMessage(msg);
11055                }
11056            }
11057        }
11058
11059        retrieveSettings();
11060        loadResourcesOnSystemReady();
11061
11062        synchronized (this) {
11063            readGrantedUriPermissionsLocked();
11064        }
11065
11066        if (goingCallback != null) goingCallback.run();
11067
11068        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11069                Integer.toString(mCurrentUserId), mCurrentUserId);
11070        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11071                Integer.toString(mCurrentUserId), mCurrentUserId);
11072        mSystemServiceManager.startUser(mCurrentUserId);
11073
11074        synchronized (this) {
11075            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11076                try {
11077                    List apps = AppGlobals.getPackageManager().
11078                        getPersistentApplications(STOCK_PM_FLAGS);
11079                    if (apps != null) {
11080                        int N = apps.size();
11081                        int i;
11082                        for (i=0; i<N; i++) {
11083                            ApplicationInfo info
11084                                = (ApplicationInfo)apps.get(i);
11085                            if (info != null &&
11086                                    !info.packageName.equals("android")) {
11087                                addAppLocked(info, false, null /* ABI override */);
11088                            }
11089                        }
11090                    }
11091                } catch (RemoteException ex) {
11092                    // pm is in same process, this will never happen.
11093                }
11094            }
11095
11096            // Start up initial activity.
11097            mBooting = true;
11098
11099            try {
11100                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11101                    Message msg = Message.obtain();
11102                    msg.what = SHOW_UID_ERROR_MSG;
11103                    mHandler.sendMessage(msg);
11104                }
11105            } catch (RemoteException e) {
11106            }
11107
11108            long ident = Binder.clearCallingIdentity();
11109            try {
11110                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11111                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11112                        | Intent.FLAG_RECEIVER_FOREGROUND);
11113                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11114                broadcastIntentLocked(null, null, intent,
11115                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11116                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11117                intent = new Intent(Intent.ACTION_USER_STARTING);
11118                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11119                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11120                broadcastIntentLocked(null, null, intent,
11121                        null, new IIntentReceiver.Stub() {
11122                            @Override
11123                            public void performReceive(Intent intent, int resultCode, String data,
11124                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11125                                    throws RemoteException {
11126                            }
11127                        }, 0, null, null,
11128                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11129                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11130            } catch (Throwable t) {
11131                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11132            } finally {
11133                Binder.restoreCallingIdentity(ident);
11134            }
11135            mStackSupervisor.resumeTopActivitiesLocked();
11136            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11137        }
11138    }
11139
11140    private boolean makeAppCrashingLocked(ProcessRecord app,
11141            String shortMsg, String longMsg, String stackTrace) {
11142        app.crashing = true;
11143        app.crashingReport = generateProcessError(app,
11144                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11145        startAppProblemLocked(app);
11146        app.stopFreezingAllLocked();
11147        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11148    }
11149
11150    private void makeAppNotRespondingLocked(ProcessRecord app,
11151            String activity, String shortMsg, String longMsg) {
11152        app.notResponding = true;
11153        app.notRespondingReport = generateProcessError(app,
11154                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11155                activity, shortMsg, longMsg, null);
11156        startAppProblemLocked(app);
11157        app.stopFreezingAllLocked();
11158    }
11159
11160    /**
11161     * Generate a process error record, suitable for attachment to a ProcessRecord.
11162     *
11163     * @param app The ProcessRecord in which the error occurred.
11164     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11165     *                      ActivityManager.AppErrorStateInfo
11166     * @param activity The activity associated with the crash, if known.
11167     * @param shortMsg Short message describing the crash.
11168     * @param longMsg Long message describing the crash.
11169     * @param stackTrace Full crash stack trace, may be null.
11170     *
11171     * @return Returns a fully-formed AppErrorStateInfo record.
11172     */
11173    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11174            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11175        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11176
11177        report.condition = condition;
11178        report.processName = app.processName;
11179        report.pid = app.pid;
11180        report.uid = app.info.uid;
11181        report.tag = activity;
11182        report.shortMsg = shortMsg;
11183        report.longMsg = longMsg;
11184        report.stackTrace = stackTrace;
11185
11186        return report;
11187    }
11188
11189    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11190        synchronized (this) {
11191            app.crashing = false;
11192            app.crashingReport = null;
11193            app.notResponding = false;
11194            app.notRespondingReport = null;
11195            if (app.anrDialog == fromDialog) {
11196                app.anrDialog = null;
11197            }
11198            if (app.waitDialog == fromDialog) {
11199                app.waitDialog = null;
11200            }
11201            if (app.pid > 0 && app.pid != MY_PID) {
11202                handleAppCrashLocked(app, null, null, null);
11203                app.kill("user request after error", true);
11204            }
11205        }
11206    }
11207
11208    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11209            String stackTrace) {
11210        long now = SystemClock.uptimeMillis();
11211
11212        Long crashTime;
11213        if (!app.isolated) {
11214            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11215        } else {
11216            crashTime = null;
11217        }
11218        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11219            // This process loses!
11220            Slog.w(TAG, "Process " + app.info.processName
11221                    + " has crashed too many times: killing!");
11222            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11223                    app.userId, app.info.processName, app.uid);
11224            mStackSupervisor.handleAppCrashLocked(app);
11225            if (!app.persistent) {
11226                // We don't want to start this process again until the user
11227                // explicitly does so...  but for persistent process, we really
11228                // need to keep it running.  If a persistent process is actually
11229                // repeatedly crashing, then badness for everyone.
11230                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11231                        app.info.processName);
11232                if (!app.isolated) {
11233                    // XXX We don't have a way to mark isolated processes
11234                    // as bad, since they don't have a peristent identity.
11235                    mBadProcesses.put(app.info.processName, app.uid,
11236                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11237                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11238                }
11239                app.bad = true;
11240                app.removed = true;
11241                // Don't let services in this process be restarted and potentially
11242                // annoy the user repeatedly.  Unless it is persistent, since those
11243                // processes run critical code.
11244                removeProcessLocked(app, false, false, "crash");
11245                mStackSupervisor.resumeTopActivitiesLocked();
11246                return false;
11247            }
11248            mStackSupervisor.resumeTopActivitiesLocked();
11249        } else {
11250            mStackSupervisor.finishTopRunningActivityLocked(app);
11251        }
11252
11253        // Bump up the crash count of any services currently running in the proc.
11254        for (int i=app.services.size()-1; i>=0; i--) {
11255            // Any services running in the application need to be placed
11256            // back in the pending list.
11257            ServiceRecord sr = app.services.valueAt(i);
11258            sr.crashCount++;
11259        }
11260
11261        // If the crashing process is what we consider to be the "home process" and it has been
11262        // replaced by a third-party app, clear the package preferred activities from packages
11263        // with a home activity running in the process to prevent a repeatedly crashing app
11264        // from blocking the user to manually clear the list.
11265        final ArrayList<ActivityRecord> activities = app.activities;
11266        if (app == mHomeProcess && activities.size() > 0
11267                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11268            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11269                final ActivityRecord r = activities.get(activityNdx);
11270                if (r.isHomeActivity()) {
11271                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11272                    try {
11273                        ActivityThread.getPackageManager()
11274                                .clearPackagePreferredActivities(r.packageName);
11275                    } catch (RemoteException c) {
11276                        // pm is in same process, this will never happen.
11277                    }
11278                }
11279            }
11280        }
11281
11282        if (!app.isolated) {
11283            // XXX Can't keep track of crash times for isolated processes,
11284            // because they don't have a perisistent identity.
11285            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11286        }
11287
11288        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11289        return true;
11290    }
11291
11292    void startAppProblemLocked(ProcessRecord app) {
11293        // If this app is not running under the current user, then we
11294        // can't give it a report button because that would require
11295        // launching the report UI under a different user.
11296        app.errorReportReceiver = null;
11297
11298        for (int userId : mCurrentProfileIds) {
11299            if (app.userId == userId) {
11300                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11301                        mContext, app.info.packageName, app.info.flags);
11302            }
11303        }
11304        skipCurrentReceiverLocked(app);
11305    }
11306
11307    void skipCurrentReceiverLocked(ProcessRecord app) {
11308        for (BroadcastQueue queue : mBroadcastQueues) {
11309            queue.skipCurrentReceiverLocked(app);
11310        }
11311    }
11312
11313    /**
11314     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11315     * The application process will exit immediately after this call returns.
11316     * @param app object of the crashing app, null for the system server
11317     * @param crashInfo describing the exception
11318     */
11319    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11320        ProcessRecord r = findAppProcess(app, "Crash");
11321        final String processName = app == null ? "system_server"
11322                : (r == null ? "unknown" : r.processName);
11323
11324        handleApplicationCrashInner("crash", r, processName, crashInfo);
11325    }
11326
11327    /* Native crash reporting uses this inner version because it needs to be somewhat
11328     * decoupled from the AM-managed cleanup lifecycle
11329     */
11330    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11331            ApplicationErrorReport.CrashInfo crashInfo) {
11332        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11333                UserHandle.getUserId(Binder.getCallingUid()), processName,
11334                r == null ? -1 : r.info.flags,
11335                crashInfo.exceptionClassName,
11336                crashInfo.exceptionMessage,
11337                crashInfo.throwFileName,
11338                crashInfo.throwLineNumber);
11339
11340        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11341
11342        crashApplication(r, crashInfo);
11343    }
11344
11345    public void handleApplicationStrictModeViolation(
11346            IBinder app,
11347            int violationMask,
11348            StrictMode.ViolationInfo info) {
11349        ProcessRecord r = findAppProcess(app, "StrictMode");
11350        if (r == null) {
11351            return;
11352        }
11353
11354        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11355            Integer stackFingerprint = info.hashCode();
11356            boolean logIt = true;
11357            synchronized (mAlreadyLoggedViolatedStacks) {
11358                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11359                    logIt = false;
11360                    // TODO: sub-sample into EventLog for these, with
11361                    // the info.durationMillis?  Then we'd get
11362                    // the relative pain numbers, without logging all
11363                    // the stack traces repeatedly.  We'd want to do
11364                    // likewise in the client code, which also does
11365                    // dup suppression, before the Binder call.
11366                } else {
11367                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11368                        mAlreadyLoggedViolatedStacks.clear();
11369                    }
11370                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11371                }
11372            }
11373            if (logIt) {
11374                logStrictModeViolationToDropBox(r, info);
11375            }
11376        }
11377
11378        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11379            AppErrorResult result = new AppErrorResult();
11380            synchronized (this) {
11381                final long origId = Binder.clearCallingIdentity();
11382
11383                Message msg = Message.obtain();
11384                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11385                HashMap<String, Object> data = new HashMap<String, Object>();
11386                data.put("result", result);
11387                data.put("app", r);
11388                data.put("violationMask", violationMask);
11389                data.put("info", info);
11390                msg.obj = data;
11391                mHandler.sendMessage(msg);
11392
11393                Binder.restoreCallingIdentity(origId);
11394            }
11395            int res = result.get();
11396            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11397        }
11398    }
11399
11400    // Depending on the policy in effect, there could be a bunch of
11401    // these in quick succession so we try to batch these together to
11402    // minimize disk writes, number of dropbox entries, and maximize
11403    // compression, by having more fewer, larger records.
11404    private void logStrictModeViolationToDropBox(
11405            ProcessRecord process,
11406            StrictMode.ViolationInfo info) {
11407        if (info == null) {
11408            return;
11409        }
11410        final boolean isSystemApp = process == null ||
11411                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11412                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11413        final String processName = process == null ? "unknown" : process.processName;
11414        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11415        final DropBoxManager dbox = (DropBoxManager)
11416                mContext.getSystemService(Context.DROPBOX_SERVICE);
11417
11418        // Exit early if the dropbox isn't configured to accept this report type.
11419        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11420
11421        boolean bufferWasEmpty;
11422        boolean needsFlush;
11423        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11424        synchronized (sb) {
11425            bufferWasEmpty = sb.length() == 0;
11426            appendDropBoxProcessHeaders(process, processName, sb);
11427            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11428            sb.append("System-App: ").append(isSystemApp).append("\n");
11429            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11430            if (info.violationNumThisLoop != 0) {
11431                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11432            }
11433            if (info.numAnimationsRunning != 0) {
11434                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11435            }
11436            if (info.broadcastIntentAction != null) {
11437                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11438            }
11439            if (info.durationMillis != -1) {
11440                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11441            }
11442            if (info.numInstances != -1) {
11443                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11444            }
11445            if (info.tags != null) {
11446                for (String tag : info.tags) {
11447                    sb.append("Span-Tag: ").append(tag).append("\n");
11448                }
11449            }
11450            sb.append("\n");
11451            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11452                sb.append(info.crashInfo.stackTrace);
11453            }
11454            sb.append("\n");
11455
11456            // Only buffer up to ~64k.  Various logging bits truncate
11457            // things at 128k.
11458            needsFlush = (sb.length() > 64 * 1024);
11459        }
11460
11461        // Flush immediately if the buffer's grown too large, or this
11462        // is a non-system app.  Non-system apps are isolated with a
11463        // different tag & policy and not batched.
11464        //
11465        // Batching is useful during internal testing with
11466        // StrictMode settings turned up high.  Without batching,
11467        // thousands of separate files could be created on boot.
11468        if (!isSystemApp || needsFlush) {
11469            new Thread("Error dump: " + dropboxTag) {
11470                @Override
11471                public void run() {
11472                    String report;
11473                    synchronized (sb) {
11474                        report = sb.toString();
11475                        sb.delete(0, sb.length());
11476                        sb.trimToSize();
11477                    }
11478                    if (report.length() != 0) {
11479                        dbox.addText(dropboxTag, report);
11480                    }
11481                }
11482            }.start();
11483            return;
11484        }
11485
11486        // System app batching:
11487        if (!bufferWasEmpty) {
11488            // An existing dropbox-writing thread is outstanding, so
11489            // we don't need to start it up.  The existing thread will
11490            // catch the buffer appends we just did.
11491            return;
11492        }
11493
11494        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11495        // (After this point, we shouldn't access AMS internal data structures.)
11496        new Thread("Error dump: " + dropboxTag) {
11497            @Override
11498            public void run() {
11499                // 5 second sleep to let stacks arrive and be batched together
11500                try {
11501                    Thread.sleep(5000);  // 5 seconds
11502                } catch (InterruptedException e) {}
11503
11504                String errorReport;
11505                synchronized (mStrictModeBuffer) {
11506                    errorReport = mStrictModeBuffer.toString();
11507                    if (errorReport.length() == 0) {
11508                        return;
11509                    }
11510                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11511                    mStrictModeBuffer.trimToSize();
11512                }
11513                dbox.addText(dropboxTag, errorReport);
11514            }
11515        }.start();
11516    }
11517
11518    /**
11519     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11520     * @param app object of the crashing app, null for the system server
11521     * @param tag reported by the caller
11522     * @param system whether this wtf is coming from the system
11523     * @param crashInfo describing the context of the error
11524     * @return true if the process should exit immediately (WTF is fatal)
11525     */
11526    public boolean handleApplicationWtf(IBinder app, final String tag, boolean system,
11527            final ApplicationErrorReport.CrashInfo crashInfo) {
11528        final ProcessRecord r = findAppProcess(app, "WTF");
11529        final String processName = app == null ? "system_server"
11530                : (r == null ? "unknown" : r.processName);
11531
11532        EventLog.writeEvent(EventLogTags.AM_WTF,
11533                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
11534                processName,
11535                r == null ? -1 : r.info.flags,
11536                tag, crashInfo.exceptionMessage);
11537
11538        if (system) {
11539            // If this is coming from the system, we could very well have low-level
11540            // system locks held, so we want to do this all asynchronously.  And we
11541            // never want this to become fatal, so there is that too.
11542            mHandler.post(new Runnable() {
11543                @Override public void run() {
11544                    addErrorToDropBox("wtf", r, processName, null, null, tag, null, null,
11545                            crashInfo);
11546                }
11547            });
11548            return false;
11549        }
11550
11551        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11552
11553        if (r != null && r.pid != Process.myPid() &&
11554                Settings.Global.getInt(mContext.getContentResolver(),
11555                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11556            crashApplication(r, crashInfo);
11557            return true;
11558        } else {
11559            return false;
11560        }
11561    }
11562
11563    /**
11564     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11565     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11566     */
11567    private ProcessRecord findAppProcess(IBinder app, String reason) {
11568        if (app == null) {
11569            return null;
11570        }
11571
11572        synchronized (this) {
11573            final int NP = mProcessNames.getMap().size();
11574            for (int ip=0; ip<NP; ip++) {
11575                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11576                final int NA = apps.size();
11577                for (int ia=0; ia<NA; ia++) {
11578                    ProcessRecord p = apps.valueAt(ia);
11579                    if (p.thread != null && p.thread.asBinder() == app) {
11580                        return p;
11581                    }
11582                }
11583            }
11584
11585            Slog.w(TAG, "Can't find mystery application for " + reason
11586                    + " from pid=" + Binder.getCallingPid()
11587                    + " uid=" + Binder.getCallingUid() + ": " + app);
11588            return null;
11589        }
11590    }
11591
11592    /**
11593     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11594     * to append various headers to the dropbox log text.
11595     */
11596    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11597            StringBuilder sb) {
11598        // Watchdog thread ends up invoking this function (with
11599        // a null ProcessRecord) to add the stack file to dropbox.
11600        // Do not acquire a lock on this (am) in such cases, as it
11601        // could cause a potential deadlock, if and when watchdog
11602        // is invoked due to unavailability of lock on am and it
11603        // would prevent watchdog from killing system_server.
11604        if (process == null) {
11605            sb.append("Process: ").append(processName).append("\n");
11606            return;
11607        }
11608        // Note: ProcessRecord 'process' is guarded by the service
11609        // instance.  (notably process.pkgList, which could otherwise change
11610        // concurrently during execution of this method)
11611        synchronized (this) {
11612            sb.append("Process: ").append(processName).append("\n");
11613            int flags = process.info.flags;
11614            IPackageManager pm = AppGlobals.getPackageManager();
11615            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11616            for (int ip=0; ip<process.pkgList.size(); ip++) {
11617                String pkg = process.pkgList.keyAt(ip);
11618                sb.append("Package: ").append(pkg);
11619                try {
11620                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11621                    if (pi != null) {
11622                        sb.append(" v").append(pi.versionCode);
11623                        if (pi.versionName != null) {
11624                            sb.append(" (").append(pi.versionName).append(")");
11625                        }
11626                    }
11627                } catch (RemoteException e) {
11628                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11629                }
11630                sb.append("\n");
11631            }
11632        }
11633    }
11634
11635    private static String processClass(ProcessRecord process) {
11636        if (process == null || process.pid == MY_PID) {
11637            return "system_server";
11638        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11639            return "system_app";
11640        } else {
11641            return "data_app";
11642        }
11643    }
11644
11645    /**
11646     * Write a description of an error (crash, WTF, ANR) to the drop box.
11647     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11648     * @param process which caused the error, null means the system server
11649     * @param activity which triggered the error, null if unknown
11650     * @param parent activity related to the error, null if unknown
11651     * @param subject line related to the error, null if absent
11652     * @param report in long form describing the error, null if absent
11653     * @param logFile to include in the report, null if none
11654     * @param crashInfo giving an application stack trace, null if absent
11655     */
11656    public void addErrorToDropBox(String eventType,
11657            ProcessRecord process, String processName, ActivityRecord activity,
11658            ActivityRecord parent, String subject,
11659            final String report, final File logFile,
11660            final ApplicationErrorReport.CrashInfo crashInfo) {
11661        // NOTE -- this must never acquire the ActivityManagerService lock,
11662        // otherwise the watchdog may be prevented from resetting the system.
11663
11664        final String dropboxTag = processClass(process) + "_" + eventType;
11665        final DropBoxManager dbox = (DropBoxManager)
11666                mContext.getSystemService(Context.DROPBOX_SERVICE);
11667
11668        // Exit early if the dropbox isn't configured to accept this report type.
11669        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11670
11671        final StringBuilder sb = new StringBuilder(1024);
11672        appendDropBoxProcessHeaders(process, processName, sb);
11673        if (activity != null) {
11674            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11675        }
11676        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11677            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11678        }
11679        if (parent != null && parent != activity) {
11680            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11681        }
11682        if (subject != null) {
11683            sb.append("Subject: ").append(subject).append("\n");
11684        }
11685        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11686        if (Debug.isDebuggerConnected()) {
11687            sb.append("Debugger: Connected\n");
11688        }
11689        sb.append("\n");
11690
11691        // Do the rest in a worker thread to avoid blocking the caller on I/O
11692        // (After this point, we shouldn't access AMS internal data structures.)
11693        Thread worker = new Thread("Error dump: " + dropboxTag) {
11694            @Override
11695            public void run() {
11696                if (report != null) {
11697                    sb.append(report);
11698                }
11699                if (logFile != null) {
11700                    try {
11701                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11702                                    "\n\n[[TRUNCATED]]"));
11703                    } catch (IOException e) {
11704                        Slog.e(TAG, "Error reading " + logFile, e);
11705                    }
11706                }
11707                if (crashInfo != null && crashInfo.stackTrace != null) {
11708                    sb.append(crashInfo.stackTrace);
11709                }
11710
11711                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11712                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11713                if (lines > 0) {
11714                    sb.append("\n");
11715
11716                    // Merge several logcat streams, and take the last N lines
11717                    InputStreamReader input = null;
11718                    try {
11719                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11720                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11721                                "-b", "crash",
11722                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11723
11724                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11725                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11726                        input = new InputStreamReader(logcat.getInputStream());
11727
11728                        int num;
11729                        char[] buf = new char[8192];
11730                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11731                    } catch (IOException e) {
11732                        Slog.e(TAG, "Error running logcat", e);
11733                    } finally {
11734                        if (input != null) try { input.close(); } catch (IOException e) {}
11735                    }
11736                }
11737
11738                dbox.addText(dropboxTag, sb.toString());
11739            }
11740        };
11741
11742        if (process == null) {
11743            // If process is null, we are being called from some internal code
11744            // and may be about to die -- run this synchronously.
11745            worker.run();
11746        } else {
11747            worker.start();
11748        }
11749    }
11750
11751    /**
11752     * Bring up the "unexpected error" dialog box for a crashing app.
11753     * Deal with edge cases (intercepts from instrumented applications,
11754     * ActivityController, error intent receivers, that sort of thing).
11755     * @param r the application crashing
11756     * @param crashInfo describing the failure
11757     */
11758    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11759        long timeMillis = System.currentTimeMillis();
11760        String shortMsg = crashInfo.exceptionClassName;
11761        String longMsg = crashInfo.exceptionMessage;
11762        String stackTrace = crashInfo.stackTrace;
11763        if (shortMsg != null && longMsg != null) {
11764            longMsg = shortMsg + ": " + longMsg;
11765        } else if (shortMsg != null) {
11766            longMsg = shortMsg;
11767        }
11768
11769        AppErrorResult result = new AppErrorResult();
11770        synchronized (this) {
11771            if (mController != null) {
11772                try {
11773                    String name = r != null ? r.processName : null;
11774                    int pid = r != null ? r.pid : Binder.getCallingPid();
11775                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11776                    if (!mController.appCrashed(name, pid,
11777                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11778                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11779                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11780                            Slog.w(TAG, "Skip killing native crashed app " + name
11781                                    + "(" + pid + ") during testing");
11782                        } else {
11783                            Slog.w(TAG, "Force-killing crashed app " + name
11784                                    + " at watcher's request");
11785                            if (r != null) {
11786                                r.kill("crash", true);
11787                            } else {
11788                                // Huh.
11789                                Process.killProcess(pid);
11790                                Process.killProcessGroup(uid, pid);
11791                            }
11792                        }
11793                        return;
11794                    }
11795                } catch (RemoteException e) {
11796                    mController = null;
11797                    Watchdog.getInstance().setActivityController(null);
11798                }
11799            }
11800
11801            final long origId = Binder.clearCallingIdentity();
11802
11803            // If this process is running instrumentation, finish it.
11804            if (r != null && r.instrumentationClass != null) {
11805                Slog.w(TAG, "Error in app " + r.processName
11806                      + " running instrumentation " + r.instrumentationClass + ":");
11807                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11808                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11809                Bundle info = new Bundle();
11810                info.putString("shortMsg", shortMsg);
11811                info.putString("longMsg", longMsg);
11812                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11813                Binder.restoreCallingIdentity(origId);
11814                return;
11815            }
11816
11817            // If we can't identify the process or it's already exceeded its crash quota,
11818            // quit right away without showing a crash dialog.
11819            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11820                Binder.restoreCallingIdentity(origId);
11821                return;
11822            }
11823
11824            Message msg = Message.obtain();
11825            msg.what = SHOW_ERROR_MSG;
11826            HashMap data = new HashMap();
11827            data.put("result", result);
11828            data.put("app", r);
11829            msg.obj = data;
11830            mHandler.sendMessage(msg);
11831
11832            Binder.restoreCallingIdentity(origId);
11833        }
11834
11835        int res = result.get();
11836
11837        Intent appErrorIntent = null;
11838        synchronized (this) {
11839            if (r != null && !r.isolated) {
11840                // XXX Can't keep track of crash time for isolated processes,
11841                // since they don't have a persistent identity.
11842                mProcessCrashTimes.put(r.info.processName, r.uid,
11843                        SystemClock.uptimeMillis());
11844            }
11845            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11846                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11847            }
11848        }
11849
11850        if (appErrorIntent != null) {
11851            try {
11852                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11853            } catch (ActivityNotFoundException e) {
11854                Slog.w(TAG, "bug report receiver dissappeared", e);
11855            }
11856        }
11857    }
11858
11859    Intent createAppErrorIntentLocked(ProcessRecord r,
11860            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11861        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11862        if (report == null) {
11863            return null;
11864        }
11865        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11866        result.setComponent(r.errorReportReceiver);
11867        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11868        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11869        return result;
11870    }
11871
11872    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11873            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11874        if (r.errorReportReceiver == null) {
11875            return null;
11876        }
11877
11878        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11879            return null;
11880        }
11881
11882        ApplicationErrorReport report = new ApplicationErrorReport();
11883        report.packageName = r.info.packageName;
11884        report.installerPackageName = r.errorReportReceiver.getPackageName();
11885        report.processName = r.processName;
11886        report.time = timeMillis;
11887        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11888
11889        if (r.crashing || r.forceCrashReport) {
11890            report.type = ApplicationErrorReport.TYPE_CRASH;
11891            report.crashInfo = crashInfo;
11892        } else if (r.notResponding) {
11893            report.type = ApplicationErrorReport.TYPE_ANR;
11894            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11895
11896            report.anrInfo.activity = r.notRespondingReport.tag;
11897            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11898            report.anrInfo.info = r.notRespondingReport.longMsg;
11899        }
11900
11901        return report;
11902    }
11903
11904    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11905        enforceNotIsolatedCaller("getProcessesInErrorState");
11906        // assume our apps are happy - lazy create the list
11907        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11908
11909        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11910                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11911        int userId = UserHandle.getUserId(Binder.getCallingUid());
11912
11913        synchronized (this) {
11914
11915            // iterate across all processes
11916            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11917                ProcessRecord app = mLruProcesses.get(i);
11918                if (!allUsers && app.userId != userId) {
11919                    continue;
11920                }
11921                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11922                    // This one's in trouble, so we'll generate a report for it
11923                    // crashes are higher priority (in case there's a crash *and* an anr)
11924                    ActivityManager.ProcessErrorStateInfo report = null;
11925                    if (app.crashing) {
11926                        report = app.crashingReport;
11927                    } else if (app.notResponding) {
11928                        report = app.notRespondingReport;
11929                    }
11930
11931                    if (report != null) {
11932                        if (errList == null) {
11933                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11934                        }
11935                        errList.add(report);
11936                    } else {
11937                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11938                                " crashing = " + app.crashing +
11939                                " notResponding = " + app.notResponding);
11940                    }
11941                }
11942            }
11943        }
11944
11945        return errList;
11946    }
11947
11948    static int procStateToImportance(int procState, int memAdj,
11949            ActivityManager.RunningAppProcessInfo currApp) {
11950        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11951        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11952            currApp.lru = memAdj;
11953        } else {
11954            currApp.lru = 0;
11955        }
11956        return imp;
11957    }
11958
11959    private void fillInProcMemInfo(ProcessRecord app,
11960            ActivityManager.RunningAppProcessInfo outInfo) {
11961        outInfo.pid = app.pid;
11962        outInfo.uid = app.info.uid;
11963        if (mHeavyWeightProcess == app) {
11964            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11965        }
11966        if (app.persistent) {
11967            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11968        }
11969        if (app.activities.size() > 0) {
11970            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11971        }
11972        outInfo.lastTrimLevel = app.trimMemoryLevel;
11973        int adj = app.curAdj;
11974        int procState = app.curProcState;
11975        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11976        outInfo.importanceReasonCode = app.adjTypeCode;
11977        outInfo.processState = app.curProcState;
11978    }
11979
11980    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11981        enforceNotIsolatedCaller("getRunningAppProcesses");
11982        // Lazy instantiation of list
11983        List<ActivityManager.RunningAppProcessInfo> runList = null;
11984        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11985                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11986        int userId = UserHandle.getUserId(Binder.getCallingUid());
11987        synchronized (this) {
11988            // Iterate across all processes
11989            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11990                ProcessRecord app = mLruProcesses.get(i);
11991                if (!allUsers && app.userId != userId) {
11992                    continue;
11993                }
11994                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11995                    // Generate process state info for running application
11996                    ActivityManager.RunningAppProcessInfo currApp =
11997                        new ActivityManager.RunningAppProcessInfo(app.processName,
11998                                app.pid, app.getPackageList());
11999                    fillInProcMemInfo(app, currApp);
12000                    if (app.adjSource instanceof ProcessRecord) {
12001                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12002                        currApp.importanceReasonImportance =
12003                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12004                                        app.adjSourceProcState);
12005                    } else if (app.adjSource instanceof ActivityRecord) {
12006                        ActivityRecord r = (ActivityRecord)app.adjSource;
12007                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12008                    }
12009                    if (app.adjTarget instanceof ComponentName) {
12010                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12011                    }
12012                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12013                    //        + " lru=" + currApp.lru);
12014                    if (runList == null) {
12015                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12016                    }
12017                    runList.add(currApp);
12018                }
12019            }
12020        }
12021        return runList;
12022    }
12023
12024    public List<ApplicationInfo> getRunningExternalApplications() {
12025        enforceNotIsolatedCaller("getRunningExternalApplications");
12026        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12027        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12028        if (runningApps != null && runningApps.size() > 0) {
12029            Set<String> extList = new HashSet<String>();
12030            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12031                if (app.pkgList != null) {
12032                    for (String pkg : app.pkgList) {
12033                        extList.add(pkg);
12034                    }
12035                }
12036            }
12037            IPackageManager pm = AppGlobals.getPackageManager();
12038            for (String pkg : extList) {
12039                try {
12040                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12041                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12042                        retList.add(info);
12043                    }
12044                } catch (RemoteException e) {
12045                }
12046            }
12047        }
12048        return retList;
12049    }
12050
12051    @Override
12052    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12053        enforceNotIsolatedCaller("getMyMemoryState");
12054        synchronized (this) {
12055            ProcessRecord proc;
12056            synchronized (mPidsSelfLocked) {
12057                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12058            }
12059            fillInProcMemInfo(proc, outInfo);
12060        }
12061    }
12062
12063    @Override
12064    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12065        if (checkCallingPermission(android.Manifest.permission.DUMP)
12066                != PackageManager.PERMISSION_GRANTED) {
12067            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12068                    + Binder.getCallingPid()
12069                    + ", uid=" + Binder.getCallingUid()
12070                    + " without permission "
12071                    + android.Manifest.permission.DUMP);
12072            return;
12073        }
12074
12075        boolean dumpAll = false;
12076        boolean dumpClient = false;
12077        String dumpPackage = null;
12078
12079        int opti = 0;
12080        while (opti < args.length) {
12081            String opt = args[opti];
12082            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12083                break;
12084            }
12085            opti++;
12086            if ("-a".equals(opt)) {
12087                dumpAll = true;
12088            } else if ("-c".equals(opt)) {
12089                dumpClient = true;
12090            } else if ("-h".equals(opt)) {
12091                pw.println("Activity manager dump options:");
12092                pw.println("  [-a] [-c] [-h] [cmd] ...");
12093                pw.println("  cmd may be one of:");
12094                pw.println("    a[ctivities]: activity stack state");
12095                pw.println("    r[recents]: recent activities state");
12096                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12097                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12098                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12099                pw.println("    o[om]: out of memory management");
12100                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12101                pw.println("    provider [COMP_SPEC]: provider client-side state");
12102                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12103                pw.println("    service [COMP_SPEC]: service client-side state");
12104                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12105                pw.println("    all: dump all activities");
12106                pw.println("    top: dump the top activity");
12107                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12108                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12109                pw.println("    a partial substring in a component name, a");
12110                pw.println("    hex object identifier.");
12111                pw.println("  -a: include all available server state.");
12112                pw.println("  -c: include client state.");
12113                return;
12114            } else {
12115                pw.println("Unknown argument: " + opt + "; use -h for help");
12116            }
12117        }
12118
12119        long origId = Binder.clearCallingIdentity();
12120        boolean more = false;
12121        // Is the caller requesting to dump a particular piece of data?
12122        if (opti < args.length) {
12123            String cmd = args[opti];
12124            opti++;
12125            if ("activities".equals(cmd) || "a".equals(cmd)) {
12126                synchronized (this) {
12127                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12128                }
12129            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12130                synchronized (this) {
12131                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12132                }
12133            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12134                String[] newArgs;
12135                String name;
12136                if (opti >= args.length) {
12137                    name = null;
12138                    newArgs = EMPTY_STRING_ARRAY;
12139                } else {
12140                    name = args[opti];
12141                    opti++;
12142                    newArgs = new String[args.length - opti];
12143                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12144                            args.length - opti);
12145                }
12146                synchronized (this) {
12147                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12148                }
12149            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12150                String[] newArgs;
12151                String name;
12152                if (opti >= args.length) {
12153                    name = null;
12154                    newArgs = EMPTY_STRING_ARRAY;
12155                } else {
12156                    name = args[opti];
12157                    opti++;
12158                    newArgs = new String[args.length - opti];
12159                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12160                            args.length - opti);
12161                }
12162                synchronized (this) {
12163                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12164                }
12165            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12166                String[] newArgs;
12167                String name;
12168                if (opti >= args.length) {
12169                    name = null;
12170                    newArgs = EMPTY_STRING_ARRAY;
12171                } else {
12172                    name = args[opti];
12173                    opti++;
12174                    newArgs = new String[args.length - opti];
12175                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12176                            args.length - opti);
12177                }
12178                synchronized (this) {
12179                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12180                }
12181            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12182                synchronized (this) {
12183                    dumpOomLocked(fd, pw, args, opti, true);
12184                }
12185            } else if ("provider".equals(cmd)) {
12186                String[] newArgs;
12187                String name;
12188                if (opti >= args.length) {
12189                    name = null;
12190                    newArgs = EMPTY_STRING_ARRAY;
12191                } else {
12192                    name = args[opti];
12193                    opti++;
12194                    newArgs = new String[args.length - opti];
12195                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12196                }
12197                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12198                    pw.println("No providers match: " + name);
12199                    pw.println("Use -h for help.");
12200                }
12201            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12202                synchronized (this) {
12203                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12204                }
12205            } else if ("service".equals(cmd)) {
12206                String[] newArgs;
12207                String name;
12208                if (opti >= args.length) {
12209                    name = null;
12210                    newArgs = EMPTY_STRING_ARRAY;
12211                } else {
12212                    name = args[opti];
12213                    opti++;
12214                    newArgs = new String[args.length - opti];
12215                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12216                            args.length - opti);
12217                }
12218                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12219                    pw.println("No services match: " + name);
12220                    pw.println("Use -h for help.");
12221                }
12222            } else if ("package".equals(cmd)) {
12223                String[] newArgs;
12224                if (opti >= args.length) {
12225                    pw.println("package: no package name specified");
12226                    pw.println("Use -h for help.");
12227                } else {
12228                    dumpPackage = args[opti];
12229                    opti++;
12230                    newArgs = new String[args.length - opti];
12231                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12232                            args.length - opti);
12233                    args = newArgs;
12234                    opti = 0;
12235                    more = true;
12236                }
12237            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12238                synchronized (this) {
12239                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12240                }
12241            } else {
12242                // Dumping a single activity?
12243                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12244                    pw.println("Bad activity command, or no activities match: " + cmd);
12245                    pw.println("Use -h for help.");
12246                }
12247            }
12248            if (!more) {
12249                Binder.restoreCallingIdentity(origId);
12250                return;
12251            }
12252        }
12253
12254        // No piece of data specified, dump everything.
12255        synchronized (this) {
12256            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12257            pw.println();
12258            if (dumpAll) {
12259                pw.println("-------------------------------------------------------------------------------");
12260            }
12261            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12262            pw.println();
12263            if (dumpAll) {
12264                pw.println("-------------------------------------------------------------------------------");
12265            }
12266            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12267            pw.println();
12268            if (dumpAll) {
12269                pw.println("-------------------------------------------------------------------------------");
12270            }
12271            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12272            pw.println();
12273            if (dumpAll) {
12274                pw.println("-------------------------------------------------------------------------------");
12275            }
12276            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12277            pw.println();
12278            if (dumpAll) {
12279                pw.println("-------------------------------------------------------------------------------");
12280            }
12281            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12282            pw.println();
12283            if (dumpAll) {
12284                pw.println("-------------------------------------------------------------------------------");
12285            }
12286            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12287        }
12288        Binder.restoreCallingIdentity(origId);
12289    }
12290
12291    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12292            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12293        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12294
12295        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12296                dumpPackage);
12297        boolean needSep = printedAnything;
12298
12299        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12300                dumpPackage, needSep, "  mFocusedActivity: ");
12301        if (printed) {
12302            printedAnything = true;
12303            needSep = false;
12304        }
12305
12306        if (dumpPackage == null) {
12307            if (needSep) {
12308                pw.println();
12309            }
12310            needSep = true;
12311            printedAnything = true;
12312            mStackSupervisor.dump(pw, "  ");
12313        }
12314
12315        if (!printedAnything) {
12316            pw.println("  (nothing)");
12317        }
12318    }
12319
12320    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12321            int opti, boolean dumpAll, String dumpPackage) {
12322        pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)");
12323
12324        boolean printedAnything = false;
12325
12326        if (mRecentTasks.size() > 0) {
12327            boolean printedHeader = false;
12328
12329            final int N = mRecentTasks.size();
12330            for (int i=0; i<N; i++) {
12331                TaskRecord tr = mRecentTasks.get(i);
12332                if (dumpPackage != null) {
12333                    if (tr.realActivity == null ||
12334                            !dumpPackage.equals(tr.realActivity)) {
12335                        continue;
12336                    }
12337                }
12338                if (!printedHeader) {
12339                    pw.println("  Recent tasks:");
12340                    printedHeader = true;
12341                    printedAnything = true;
12342                }
12343                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12344                        pw.println(tr);
12345                if (dumpAll) {
12346                    mRecentTasks.get(i).dump(pw, "    ");
12347                }
12348            }
12349        }
12350
12351        if (!printedAnything) {
12352            pw.println("  (nothing)");
12353        }
12354    }
12355
12356    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12357            int opti, boolean dumpAll, String dumpPackage) {
12358        boolean needSep = false;
12359        boolean printedAnything = false;
12360        int numPers = 0;
12361
12362        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12363
12364        if (dumpAll) {
12365            final int NP = mProcessNames.getMap().size();
12366            for (int ip=0; ip<NP; ip++) {
12367                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12368                final int NA = procs.size();
12369                for (int ia=0; ia<NA; ia++) {
12370                    ProcessRecord r = procs.valueAt(ia);
12371                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12372                        continue;
12373                    }
12374                    if (!needSep) {
12375                        pw.println("  All known processes:");
12376                        needSep = true;
12377                        printedAnything = true;
12378                    }
12379                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12380                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12381                        pw.print(" "); pw.println(r);
12382                    r.dump(pw, "    ");
12383                    if (r.persistent) {
12384                        numPers++;
12385                    }
12386                }
12387            }
12388        }
12389
12390        if (mIsolatedProcesses.size() > 0) {
12391            boolean printed = false;
12392            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12393                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12394                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12395                    continue;
12396                }
12397                if (!printed) {
12398                    if (needSep) {
12399                        pw.println();
12400                    }
12401                    pw.println("  Isolated process list (sorted by uid):");
12402                    printedAnything = true;
12403                    printed = true;
12404                    needSep = true;
12405                }
12406                pw.println(String.format("%sIsolated #%2d: %s",
12407                        "    ", i, r.toString()));
12408            }
12409        }
12410
12411        if (mLruProcesses.size() > 0) {
12412            if (needSep) {
12413                pw.println();
12414            }
12415            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12416                    pw.print(" total, non-act at ");
12417                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12418                    pw.print(", non-svc at ");
12419                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12420                    pw.println("):");
12421            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12422            needSep = true;
12423            printedAnything = true;
12424        }
12425
12426        if (dumpAll || dumpPackage != null) {
12427            synchronized (mPidsSelfLocked) {
12428                boolean printed = false;
12429                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12430                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12431                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12432                        continue;
12433                    }
12434                    if (!printed) {
12435                        if (needSep) pw.println();
12436                        needSep = true;
12437                        pw.println("  PID mappings:");
12438                        printed = true;
12439                        printedAnything = true;
12440                    }
12441                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12442                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12443                }
12444            }
12445        }
12446
12447        if (mForegroundProcesses.size() > 0) {
12448            synchronized (mPidsSelfLocked) {
12449                boolean printed = false;
12450                for (int i=0; i<mForegroundProcesses.size(); i++) {
12451                    ProcessRecord r = mPidsSelfLocked.get(
12452                            mForegroundProcesses.valueAt(i).pid);
12453                    if (dumpPackage != null && (r == null
12454                            || !r.pkgList.containsKey(dumpPackage))) {
12455                        continue;
12456                    }
12457                    if (!printed) {
12458                        if (needSep) pw.println();
12459                        needSep = true;
12460                        pw.println("  Foreground Processes:");
12461                        printed = true;
12462                        printedAnything = true;
12463                    }
12464                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12465                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12466                }
12467            }
12468        }
12469
12470        if (mPersistentStartingProcesses.size() > 0) {
12471            if (needSep) pw.println();
12472            needSep = true;
12473            printedAnything = true;
12474            pw.println("  Persisent processes that are starting:");
12475            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12476                    "Starting Norm", "Restarting PERS", dumpPackage);
12477        }
12478
12479        if (mRemovedProcesses.size() > 0) {
12480            if (needSep) pw.println();
12481            needSep = true;
12482            printedAnything = true;
12483            pw.println("  Processes that are being removed:");
12484            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12485                    "Removed Norm", "Removed PERS", dumpPackage);
12486        }
12487
12488        if (mProcessesOnHold.size() > 0) {
12489            if (needSep) pw.println();
12490            needSep = true;
12491            printedAnything = true;
12492            pw.println("  Processes that are on old until the system is ready:");
12493            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12494                    "OnHold Norm", "OnHold PERS", dumpPackage);
12495        }
12496
12497        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12498
12499        if (mProcessCrashTimes.getMap().size() > 0) {
12500            boolean printed = false;
12501            long now = SystemClock.uptimeMillis();
12502            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12503            final int NP = pmap.size();
12504            for (int ip=0; ip<NP; ip++) {
12505                String pname = pmap.keyAt(ip);
12506                SparseArray<Long> uids = pmap.valueAt(ip);
12507                final int N = uids.size();
12508                for (int i=0; i<N; i++) {
12509                    int puid = uids.keyAt(i);
12510                    ProcessRecord r = mProcessNames.get(pname, puid);
12511                    if (dumpPackage != null && (r == null
12512                            || !r.pkgList.containsKey(dumpPackage))) {
12513                        continue;
12514                    }
12515                    if (!printed) {
12516                        if (needSep) pw.println();
12517                        needSep = true;
12518                        pw.println("  Time since processes crashed:");
12519                        printed = true;
12520                        printedAnything = true;
12521                    }
12522                    pw.print("    Process "); pw.print(pname);
12523                            pw.print(" uid "); pw.print(puid);
12524                            pw.print(": last crashed ");
12525                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12526                            pw.println(" ago");
12527                }
12528            }
12529        }
12530
12531        if (mBadProcesses.getMap().size() > 0) {
12532            boolean printed = false;
12533            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12534            final int NP = pmap.size();
12535            for (int ip=0; ip<NP; ip++) {
12536                String pname = pmap.keyAt(ip);
12537                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12538                final int N = uids.size();
12539                for (int i=0; i<N; i++) {
12540                    int puid = uids.keyAt(i);
12541                    ProcessRecord r = mProcessNames.get(pname, puid);
12542                    if (dumpPackage != null && (r == null
12543                            || !r.pkgList.containsKey(dumpPackage))) {
12544                        continue;
12545                    }
12546                    if (!printed) {
12547                        if (needSep) pw.println();
12548                        needSep = true;
12549                        pw.println("  Bad processes:");
12550                        printedAnything = true;
12551                    }
12552                    BadProcessInfo info = uids.valueAt(i);
12553                    pw.print("    Bad process "); pw.print(pname);
12554                            pw.print(" uid "); pw.print(puid);
12555                            pw.print(": crashed at time "); pw.println(info.time);
12556                    if (info.shortMsg != null) {
12557                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12558                    }
12559                    if (info.longMsg != null) {
12560                        pw.print("      Long msg: "); pw.println(info.longMsg);
12561                    }
12562                    if (info.stack != null) {
12563                        pw.println("      Stack:");
12564                        int lastPos = 0;
12565                        for (int pos=0; pos<info.stack.length(); pos++) {
12566                            if (info.stack.charAt(pos) == '\n') {
12567                                pw.print("        ");
12568                                pw.write(info.stack, lastPos, pos-lastPos);
12569                                pw.println();
12570                                lastPos = pos+1;
12571                            }
12572                        }
12573                        if (lastPos < info.stack.length()) {
12574                            pw.print("        ");
12575                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12576                            pw.println();
12577                        }
12578                    }
12579                }
12580            }
12581        }
12582
12583        if (dumpPackage == null) {
12584            pw.println();
12585            needSep = false;
12586            pw.println("  mStartedUsers:");
12587            for (int i=0; i<mStartedUsers.size(); i++) {
12588                UserStartedState uss = mStartedUsers.valueAt(i);
12589                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12590                        pw.print(": "); uss.dump("", pw);
12591            }
12592            pw.print("  mStartedUserArray: [");
12593            for (int i=0; i<mStartedUserArray.length; i++) {
12594                if (i > 0) pw.print(", ");
12595                pw.print(mStartedUserArray[i]);
12596            }
12597            pw.println("]");
12598            pw.print("  mUserLru: [");
12599            for (int i=0; i<mUserLru.size(); i++) {
12600                if (i > 0) pw.print(", ");
12601                pw.print(mUserLru.get(i));
12602            }
12603            pw.println("]");
12604            if (dumpAll) {
12605                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12606            }
12607            synchronized (mUserProfileGroupIdsSelfLocked) {
12608                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12609                    pw.println("  mUserProfileGroupIds:");
12610                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12611                        pw.print("    User #");
12612                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12613                        pw.print(" -> profile #");
12614                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12615                    }
12616                }
12617            }
12618        }
12619        if (mHomeProcess != null && (dumpPackage == null
12620                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12621            if (needSep) {
12622                pw.println();
12623                needSep = false;
12624            }
12625            pw.println("  mHomeProcess: " + mHomeProcess);
12626        }
12627        if (mPreviousProcess != null && (dumpPackage == null
12628                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12629            if (needSep) {
12630                pw.println();
12631                needSep = false;
12632            }
12633            pw.println("  mPreviousProcess: " + mPreviousProcess);
12634        }
12635        if (dumpAll) {
12636            StringBuilder sb = new StringBuilder(128);
12637            sb.append("  mPreviousProcessVisibleTime: ");
12638            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12639            pw.println(sb);
12640        }
12641        if (mHeavyWeightProcess != null && (dumpPackage == null
12642                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12643            if (needSep) {
12644                pw.println();
12645                needSep = false;
12646            }
12647            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12648        }
12649        if (dumpPackage == null) {
12650            pw.println("  mConfiguration: " + mConfiguration);
12651        }
12652        if (dumpAll) {
12653            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12654            if (mCompatModePackages.getPackages().size() > 0) {
12655                boolean printed = false;
12656                for (Map.Entry<String, Integer> entry
12657                        : mCompatModePackages.getPackages().entrySet()) {
12658                    String pkg = entry.getKey();
12659                    int mode = entry.getValue();
12660                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12661                        continue;
12662                    }
12663                    if (!printed) {
12664                        pw.println("  mScreenCompatPackages:");
12665                        printed = true;
12666                    }
12667                    pw.print("    "); pw.print(pkg); pw.print(": ");
12668                            pw.print(mode); pw.println();
12669                }
12670            }
12671        }
12672        if (dumpPackage == null) {
12673            if (mSleeping || mWentToSleep || mLockScreenShown) {
12674                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12675                        + " mLockScreenShown " + mLockScreenShown);
12676            }
12677            if (mShuttingDown || mRunningVoice) {
12678                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12679            }
12680        }
12681        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12682                || mOrigWaitForDebugger) {
12683            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12684                    || dumpPackage.equals(mOrigDebugApp)) {
12685                if (needSep) {
12686                    pw.println();
12687                    needSep = false;
12688                }
12689                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12690                        + " mDebugTransient=" + mDebugTransient
12691                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12692            }
12693        }
12694        if (mOpenGlTraceApp != null) {
12695            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12696                if (needSep) {
12697                    pw.println();
12698                    needSep = false;
12699                }
12700                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12701            }
12702        }
12703        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12704                || mProfileFd != null) {
12705            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12706                if (needSep) {
12707                    pw.println();
12708                    needSep = false;
12709                }
12710                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12711                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12712                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12713                        + mAutoStopProfiler);
12714                pw.println("  mProfileType=" + mProfileType);
12715            }
12716        }
12717        if (dumpPackage == null) {
12718            if (mAlwaysFinishActivities || mController != null) {
12719                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12720                        + " mController=" + mController);
12721            }
12722            if (dumpAll) {
12723                pw.println("  Total persistent processes: " + numPers);
12724                pw.println("  mProcessesReady=" + mProcessesReady
12725                        + " mSystemReady=" + mSystemReady);
12726                pw.println("  mBooting=" + mBooting
12727                        + " mBooted=" + mBooted
12728                        + " mFactoryTest=" + mFactoryTest);
12729                pw.print("  mLastPowerCheckRealtime=");
12730                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12731                        pw.println("");
12732                pw.print("  mLastPowerCheckUptime=");
12733                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12734                        pw.println("");
12735                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12736                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12737                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12738                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12739                        + " (" + mLruProcesses.size() + " total)"
12740                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12741                        + " mNumServiceProcs=" + mNumServiceProcs
12742                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12743                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12744                        + " mLastMemoryLevel" + mLastMemoryLevel
12745                        + " mLastNumProcesses" + mLastNumProcesses);
12746                long now = SystemClock.uptimeMillis();
12747                pw.print("  mLastIdleTime=");
12748                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12749                        pw.print(" mLowRamSinceLastIdle=");
12750                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12751                        pw.println();
12752            }
12753        }
12754
12755        if (!printedAnything) {
12756            pw.println("  (nothing)");
12757        }
12758    }
12759
12760    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12761            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12762        if (mProcessesToGc.size() > 0) {
12763            boolean printed = false;
12764            long now = SystemClock.uptimeMillis();
12765            for (int i=0; i<mProcessesToGc.size(); i++) {
12766                ProcessRecord proc = mProcessesToGc.get(i);
12767                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12768                    continue;
12769                }
12770                if (!printed) {
12771                    if (needSep) pw.println();
12772                    needSep = true;
12773                    pw.println("  Processes that are waiting to GC:");
12774                    printed = true;
12775                }
12776                pw.print("    Process "); pw.println(proc);
12777                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12778                        pw.print(", last gced=");
12779                        pw.print(now-proc.lastRequestedGc);
12780                        pw.print(" ms ago, last lowMem=");
12781                        pw.print(now-proc.lastLowMemory);
12782                        pw.println(" ms ago");
12783
12784            }
12785        }
12786        return needSep;
12787    }
12788
12789    void printOomLevel(PrintWriter pw, String name, int adj) {
12790        pw.print("    ");
12791        if (adj >= 0) {
12792            pw.print(' ');
12793            if (adj < 10) pw.print(' ');
12794        } else {
12795            if (adj > -10) pw.print(' ');
12796        }
12797        pw.print(adj);
12798        pw.print(": ");
12799        pw.print(name);
12800        pw.print(" (");
12801        pw.print(mProcessList.getMemLevel(adj)/1024);
12802        pw.println(" kB)");
12803    }
12804
12805    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12806            int opti, boolean dumpAll) {
12807        boolean needSep = false;
12808
12809        if (mLruProcesses.size() > 0) {
12810            if (needSep) pw.println();
12811            needSep = true;
12812            pw.println("  OOM levels:");
12813            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12814            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12815            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12816            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12817            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12818            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12819            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12820            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12821            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12822            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12823            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12824            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12825            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12826
12827            if (needSep) pw.println();
12828            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12829                    pw.print(" total, non-act at ");
12830                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12831                    pw.print(", non-svc at ");
12832                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12833                    pw.println("):");
12834            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12835            needSep = true;
12836        }
12837
12838        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12839
12840        pw.println();
12841        pw.println("  mHomeProcess: " + mHomeProcess);
12842        pw.println("  mPreviousProcess: " + mPreviousProcess);
12843        if (mHeavyWeightProcess != null) {
12844            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12845        }
12846
12847        return true;
12848    }
12849
12850    /**
12851     * There are three ways to call this:
12852     *  - no provider specified: dump all the providers
12853     *  - a flattened component name that matched an existing provider was specified as the
12854     *    first arg: dump that one provider
12855     *  - the first arg isn't the flattened component name of an existing provider:
12856     *    dump all providers whose component contains the first arg as a substring
12857     */
12858    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12859            int opti, boolean dumpAll) {
12860        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12861    }
12862
12863    static class ItemMatcher {
12864        ArrayList<ComponentName> components;
12865        ArrayList<String> strings;
12866        ArrayList<Integer> objects;
12867        boolean all;
12868
12869        ItemMatcher() {
12870            all = true;
12871        }
12872
12873        void build(String name) {
12874            ComponentName componentName = ComponentName.unflattenFromString(name);
12875            if (componentName != null) {
12876                if (components == null) {
12877                    components = new ArrayList<ComponentName>();
12878                }
12879                components.add(componentName);
12880                all = false;
12881            } else {
12882                int objectId = 0;
12883                // Not a '/' separated full component name; maybe an object ID?
12884                try {
12885                    objectId = Integer.parseInt(name, 16);
12886                    if (objects == null) {
12887                        objects = new ArrayList<Integer>();
12888                    }
12889                    objects.add(objectId);
12890                    all = false;
12891                } catch (RuntimeException e) {
12892                    // Not an integer; just do string match.
12893                    if (strings == null) {
12894                        strings = new ArrayList<String>();
12895                    }
12896                    strings.add(name);
12897                    all = false;
12898                }
12899            }
12900        }
12901
12902        int build(String[] args, int opti) {
12903            for (; opti<args.length; opti++) {
12904                String name = args[opti];
12905                if ("--".equals(name)) {
12906                    return opti+1;
12907                }
12908                build(name);
12909            }
12910            return opti;
12911        }
12912
12913        boolean match(Object object, ComponentName comp) {
12914            if (all) {
12915                return true;
12916            }
12917            if (components != null) {
12918                for (int i=0; i<components.size(); i++) {
12919                    if (components.get(i).equals(comp)) {
12920                        return true;
12921                    }
12922                }
12923            }
12924            if (objects != null) {
12925                for (int i=0; i<objects.size(); i++) {
12926                    if (System.identityHashCode(object) == objects.get(i)) {
12927                        return true;
12928                    }
12929                }
12930            }
12931            if (strings != null) {
12932                String flat = comp.flattenToString();
12933                for (int i=0; i<strings.size(); i++) {
12934                    if (flat.contains(strings.get(i))) {
12935                        return true;
12936                    }
12937                }
12938            }
12939            return false;
12940        }
12941    }
12942
12943    /**
12944     * There are three things that cmd can be:
12945     *  - a flattened component name that matches an existing activity
12946     *  - the cmd arg isn't the flattened component name of an existing activity:
12947     *    dump all activity whose component contains the cmd as a substring
12948     *  - A hex number of the ActivityRecord object instance.
12949     */
12950    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12951            int opti, boolean dumpAll) {
12952        ArrayList<ActivityRecord> activities;
12953
12954        synchronized (this) {
12955            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12956        }
12957
12958        if (activities.size() <= 0) {
12959            return false;
12960        }
12961
12962        String[] newArgs = new String[args.length - opti];
12963        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12964
12965        TaskRecord lastTask = null;
12966        boolean needSep = false;
12967        for (int i=activities.size()-1; i>=0; i--) {
12968            ActivityRecord r = activities.get(i);
12969            if (needSep) {
12970                pw.println();
12971            }
12972            needSep = true;
12973            synchronized (this) {
12974                if (lastTask != r.task) {
12975                    lastTask = r.task;
12976                    pw.print("TASK "); pw.print(lastTask.affinity);
12977                            pw.print(" id="); pw.println(lastTask.taskId);
12978                    if (dumpAll) {
12979                        lastTask.dump(pw, "  ");
12980                    }
12981                }
12982            }
12983            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12984        }
12985        return true;
12986    }
12987
12988    /**
12989     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12990     * there is a thread associated with the activity.
12991     */
12992    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12993            final ActivityRecord r, String[] args, boolean dumpAll) {
12994        String innerPrefix = prefix + "  ";
12995        synchronized (this) {
12996            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12997                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12998                    pw.print(" pid=");
12999                    if (r.app != null) pw.println(r.app.pid);
13000                    else pw.println("(not running)");
13001            if (dumpAll) {
13002                r.dump(pw, innerPrefix);
13003            }
13004        }
13005        if (r.app != null && r.app.thread != null) {
13006            // flush anything that is already in the PrintWriter since the thread is going
13007            // to write to the file descriptor directly
13008            pw.flush();
13009            try {
13010                TransferPipe tp = new TransferPipe();
13011                try {
13012                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13013                            r.appToken, innerPrefix, args);
13014                    tp.go(fd);
13015                } finally {
13016                    tp.kill();
13017                }
13018            } catch (IOException e) {
13019                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13020            } catch (RemoteException e) {
13021                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13022            }
13023        }
13024    }
13025
13026    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13027            int opti, boolean dumpAll, String dumpPackage) {
13028        boolean needSep = false;
13029        boolean onlyHistory = false;
13030        boolean printedAnything = false;
13031
13032        if ("history".equals(dumpPackage)) {
13033            if (opti < args.length && "-s".equals(args[opti])) {
13034                dumpAll = false;
13035            }
13036            onlyHistory = true;
13037            dumpPackage = null;
13038        }
13039
13040        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13041        if (!onlyHistory && dumpAll) {
13042            if (mRegisteredReceivers.size() > 0) {
13043                boolean printed = false;
13044                Iterator it = mRegisteredReceivers.values().iterator();
13045                while (it.hasNext()) {
13046                    ReceiverList r = (ReceiverList)it.next();
13047                    if (dumpPackage != null && (r.app == null ||
13048                            !dumpPackage.equals(r.app.info.packageName))) {
13049                        continue;
13050                    }
13051                    if (!printed) {
13052                        pw.println("  Registered Receivers:");
13053                        needSep = true;
13054                        printed = true;
13055                        printedAnything = true;
13056                    }
13057                    pw.print("  * "); pw.println(r);
13058                    r.dump(pw, "    ");
13059                }
13060            }
13061
13062            if (mReceiverResolver.dump(pw, needSep ?
13063                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13064                    "    ", dumpPackage, false)) {
13065                needSep = true;
13066                printedAnything = true;
13067            }
13068        }
13069
13070        for (BroadcastQueue q : mBroadcastQueues) {
13071            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13072            printedAnything |= needSep;
13073        }
13074
13075        needSep = true;
13076
13077        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13078            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13079                if (needSep) {
13080                    pw.println();
13081                }
13082                needSep = true;
13083                printedAnything = true;
13084                pw.print("  Sticky broadcasts for user ");
13085                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13086                StringBuilder sb = new StringBuilder(128);
13087                for (Map.Entry<String, ArrayList<Intent>> ent
13088                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13089                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13090                    if (dumpAll) {
13091                        pw.println(":");
13092                        ArrayList<Intent> intents = ent.getValue();
13093                        final int N = intents.size();
13094                        for (int i=0; i<N; i++) {
13095                            sb.setLength(0);
13096                            sb.append("    Intent: ");
13097                            intents.get(i).toShortString(sb, false, true, false, false);
13098                            pw.println(sb.toString());
13099                            Bundle bundle = intents.get(i).getExtras();
13100                            if (bundle != null) {
13101                                pw.print("      ");
13102                                pw.println(bundle.toString());
13103                            }
13104                        }
13105                    } else {
13106                        pw.println("");
13107                    }
13108                }
13109            }
13110        }
13111
13112        if (!onlyHistory && dumpAll) {
13113            pw.println();
13114            for (BroadcastQueue queue : mBroadcastQueues) {
13115                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13116                        + queue.mBroadcastsScheduled);
13117            }
13118            pw.println("  mHandler:");
13119            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13120            needSep = true;
13121            printedAnything = true;
13122        }
13123
13124        if (!printedAnything) {
13125            pw.println("  (nothing)");
13126        }
13127    }
13128
13129    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13130            int opti, boolean dumpAll, String dumpPackage) {
13131        boolean needSep;
13132        boolean printedAnything = false;
13133
13134        ItemMatcher matcher = new ItemMatcher();
13135        matcher.build(args, opti);
13136
13137        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13138
13139        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13140        printedAnything |= needSep;
13141
13142        if (mLaunchingProviders.size() > 0) {
13143            boolean printed = false;
13144            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13145                ContentProviderRecord r = mLaunchingProviders.get(i);
13146                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13147                    continue;
13148                }
13149                if (!printed) {
13150                    if (needSep) pw.println();
13151                    needSep = true;
13152                    pw.println("  Launching content providers:");
13153                    printed = true;
13154                    printedAnything = true;
13155                }
13156                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13157                        pw.println(r);
13158            }
13159        }
13160
13161        if (mGrantedUriPermissions.size() > 0) {
13162            boolean printed = false;
13163            int dumpUid = -2;
13164            if (dumpPackage != null) {
13165                try {
13166                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13167                } catch (NameNotFoundException e) {
13168                    dumpUid = -1;
13169                }
13170            }
13171            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13172                int uid = mGrantedUriPermissions.keyAt(i);
13173                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13174                    continue;
13175                }
13176                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13177                if (!printed) {
13178                    if (needSep) pw.println();
13179                    needSep = true;
13180                    pw.println("  Granted Uri Permissions:");
13181                    printed = true;
13182                    printedAnything = true;
13183                }
13184                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13185                for (UriPermission perm : perms.values()) {
13186                    pw.print("    "); pw.println(perm);
13187                    if (dumpAll) {
13188                        perm.dump(pw, "      ");
13189                    }
13190                }
13191            }
13192        }
13193
13194        if (!printedAnything) {
13195            pw.println("  (nothing)");
13196        }
13197    }
13198
13199    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13200            int opti, boolean dumpAll, String dumpPackage) {
13201        boolean printed = false;
13202
13203        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13204
13205        if (mIntentSenderRecords.size() > 0) {
13206            Iterator<WeakReference<PendingIntentRecord>> it
13207                    = mIntentSenderRecords.values().iterator();
13208            while (it.hasNext()) {
13209                WeakReference<PendingIntentRecord> ref = it.next();
13210                PendingIntentRecord rec = ref != null ? ref.get(): null;
13211                if (dumpPackage != null && (rec == null
13212                        || !dumpPackage.equals(rec.key.packageName))) {
13213                    continue;
13214                }
13215                printed = true;
13216                if (rec != null) {
13217                    pw.print("  * "); pw.println(rec);
13218                    if (dumpAll) {
13219                        rec.dump(pw, "    ");
13220                    }
13221                } else {
13222                    pw.print("  * "); pw.println(ref);
13223                }
13224            }
13225        }
13226
13227        if (!printed) {
13228            pw.println("  (nothing)");
13229        }
13230    }
13231
13232    private static final int dumpProcessList(PrintWriter pw,
13233            ActivityManagerService service, List list,
13234            String prefix, String normalLabel, String persistentLabel,
13235            String dumpPackage) {
13236        int numPers = 0;
13237        final int N = list.size()-1;
13238        for (int i=N; i>=0; i--) {
13239            ProcessRecord r = (ProcessRecord)list.get(i);
13240            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13241                continue;
13242            }
13243            pw.println(String.format("%s%s #%2d: %s",
13244                    prefix, (r.persistent ? persistentLabel : normalLabel),
13245                    i, r.toString()));
13246            if (r.persistent) {
13247                numPers++;
13248            }
13249        }
13250        return numPers;
13251    }
13252
13253    private static final boolean dumpProcessOomList(PrintWriter pw,
13254            ActivityManagerService service, List<ProcessRecord> origList,
13255            String prefix, String normalLabel, String persistentLabel,
13256            boolean inclDetails, String dumpPackage) {
13257
13258        ArrayList<Pair<ProcessRecord, Integer>> list
13259                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13260        for (int i=0; i<origList.size(); i++) {
13261            ProcessRecord r = origList.get(i);
13262            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13263                continue;
13264            }
13265            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13266        }
13267
13268        if (list.size() <= 0) {
13269            return false;
13270        }
13271
13272        Comparator<Pair<ProcessRecord, Integer>> comparator
13273                = new Comparator<Pair<ProcessRecord, Integer>>() {
13274            @Override
13275            public int compare(Pair<ProcessRecord, Integer> object1,
13276                    Pair<ProcessRecord, Integer> object2) {
13277                if (object1.first.setAdj != object2.first.setAdj) {
13278                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13279                }
13280                if (object1.second.intValue() != object2.second.intValue()) {
13281                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13282                }
13283                return 0;
13284            }
13285        };
13286
13287        Collections.sort(list, comparator);
13288
13289        final long curRealtime = SystemClock.elapsedRealtime();
13290        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13291        final long curUptime = SystemClock.uptimeMillis();
13292        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13293
13294        for (int i=list.size()-1; i>=0; i--) {
13295            ProcessRecord r = list.get(i).first;
13296            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13297            char schedGroup;
13298            switch (r.setSchedGroup) {
13299                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13300                    schedGroup = 'B';
13301                    break;
13302                case Process.THREAD_GROUP_DEFAULT:
13303                    schedGroup = 'F';
13304                    break;
13305                default:
13306                    schedGroup = '?';
13307                    break;
13308            }
13309            char foreground;
13310            if (r.foregroundActivities) {
13311                foreground = 'A';
13312            } else if (r.foregroundServices) {
13313                foreground = 'S';
13314            } else {
13315                foreground = ' ';
13316            }
13317            String procState = ProcessList.makeProcStateString(r.curProcState);
13318            pw.print(prefix);
13319            pw.print(r.persistent ? persistentLabel : normalLabel);
13320            pw.print(" #");
13321            int num = (origList.size()-1)-list.get(i).second;
13322            if (num < 10) pw.print(' ');
13323            pw.print(num);
13324            pw.print(": ");
13325            pw.print(oomAdj);
13326            pw.print(' ');
13327            pw.print(schedGroup);
13328            pw.print('/');
13329            pw.print(foreground);
13330            pw.print('/');
13331            pw.print(procState);
13332            pw.print(" trm:");
13333            if (r.trimMemoryLevel < 10) pw.print(' ');
13334            pw.print(r.trimMemoryLevel);
13335            pw.print(' ');
13336            pw.print(r.toShortString());
13337            pw.print(" (");
13338            pw.print(r.adjType);
13339            pw.println(')');
13340            if (r.adjSource != null || r.adjTarget != null) {
13341                pw.print(prefix);
13342                pw.print("    ");
13343                if (r.adjTarget instanceof ComponentName) {
13344                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13345                } else if (r.adjTarget != null) {
13346                    pw.print(r.adjTarget.toString());
13347                } else {
13348                    pw.print("{null}");
13349                }
13350                pw.print("<=");
13351                if (r.adjSource instanceof ProcessRecord) {
13352                    pw.print("Proc{");
13353                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13354                    pw.println("}");
13355                } else if (r.adjSource != null) {
13356                    pw.println(r.adjSource.toString());
13357                } else {
13358                    pw.println("{null}");
13359                }
13360            }
13361            if (inclDetails) {
13362                pw.print(prefix);
13363                pw.print("    ");
13364                pw.print("oom: max="); pw.print(r.maxAdj);
13365                pw.print(" curRaw="); pw.print(r.curRawAdj);
13366                pw.print(" setRaw="); pw.print(r.setRawAdj);
13367                pw.print(" cur="); pw.print(r.curAdj);
13368                pw.print(" set="); pw.println(r.setAdj);
13369                pw.print(prefix);
13370                pw.print("    ");
13371                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13372                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13373                pw.print(" lastPss="); pw.print(r.lastPss);
13374                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13375                pw.print(prefix);
13376                pw.print("    ");
13377                pw.print("cached="); pw.print(r.cached);
13378                pw.print(" empty="); pw.print(r.empty);
13379                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13380
13381                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13382                    if (r.lastWakeTime != 0) {
13383                        long wtime;
13384                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13385                        synchronized (stats) {
13386                            wtime = stats.getProcessWakeTime(r.info.uid,
13387                                    r.pid, curRealtime);
13388                        }
13389                        long timeUsed = wtime - r.lastWakeTime;
13390                        pw.print(prefix);
13391                        pw.print("    ");
13392                        pw.print("keep awake over ");
13393                        TimeUtils.formatDuration(realtimeSince, pw);
13394                        pw.print(" used ");
13395                        TimeUtils.formatDuration(timeUsed, pw);
13396                        pw.print(" (");
13397                        pw.print((timeUsed*100)/realtimeSince);
13398                        pw.println("%)");
13399                    }
13400                    if (r.lastCpuTime != 0) {
13401                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13402                        pw.print(prefix);
13403                        pw.print("    ");
13404                        pw.print("run cpu over ");
13405                        TimeUtils.formatDuration(uptimeSince, pw);
13406                        pw.print(" used ");
13407                        TimeUtils.formatDuration(timeUsed, pw);
13408                        pw.print(" (");
13409                        pw.print((timeUsed*100)/uptimeSince);
13410                        pw.println("%)");
13411                    }
13412                }
13413            }
13414        }
13415        return true;
13416    }
13417
13418    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
13419        ArrayList<ProcessRecord> procs;
13420        synchronized (this) {
13421            if (args != null && args.length > start
13422                    && args[start].charAt(0) != '-') {
13423                procs = new ArrayList<ProcessRecord>();
13424                int pid = -1;
13425                try {
13426                    pid = Integer.parseInt(args[start]);
13427                } catch (NumberFormatException e) {
13428                }
13429                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13430                    ProcessRecord proc = mLruProcesses.get(i);
13431                    if (proc.pid == pid) {
13432                        procs.add(proc);
13433                    } else if (proc.processName.equals(args[start])) {
13434                        procs.add(proc);
13435                    }
13436                }
13437                if (procs.size() <= 0) {
13438                    return null;
13439                }
13440            } else {
13441                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13442            }
13443        }
13444        return procs;
13445    }
13446
13447    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13448            PrintWriter pw, String[] args) {
13449        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13450        if (procs == null) {
13451            pw.println("No process found for: " + args[0]);
13452            return;
13453        }
13454
13455        long uptime = SystemClock.uptimeMillis();
13456        long realtime = SystemClock.elapsedRealtime();
13457        pw.println("Applications Graphics Acceleration Info:");
13458        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13459
13460        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13461            ProcessRecord r = procs.get(i);
13462            if (r.thread != null) {
13463                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13464                pw.flush();
13465                try {
13466                    TransferPipe tp = new TransferPipe();
13467                    try {
13468                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13469                        tp.go(fd);
13470                    } finally {
13471                        tp.kill();
13472                    }
13473                } catch (IOException e) {
13474                    pw.println("Failure while dumping the app: " + r);
13475                    pw.flush();
13476                } catch (RemoteException e) {
13477                    pw.println("Got a RemoteException while dumping the app " + r);
13478                    pw.flush();
13479                }
13480            }
13481        }
13482    }
13483
13484    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13485        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13486        if (procs == null) {
13487            pw.println("No process found for: " + args[0]);
13488            return;
13489        }
13490
13491        pw.println("Applications Database Info:");
13492
13493        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13494            ProcessRecord r = procs.get(i);
13495            if (r.thread != null) {
13496                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13497                pw.flush();
13498                try {
13499                    TransferPipe tp = new TransferPipe();
13500                    try {
13501                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13502                        tp.go(fd);
13503                    } finally {
13504                        tp.kill();
13505                    }
13506                } catch (IOException e) {
13507                    pw.println("Failure while dumping the app: " + r);
13508                    pw.flush();
13509                } catch (RemoteException e) {
13510                    pw.println("Got a RemoteException while dumping the app " + r);
13511                    pw.flush();
13512                }
13513            }
13514        }
13515    }
13516
13517    final static class MemItem {
13518        final boolean isProc;
13519        final String label;
13520        final String shortLabel;
13521        final long pss;
13522        final int id;
13523        final boolean hasActivities;
13524        ArrayList<MemItem> subitems;
13525
13526        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13527                boolean _hasActivities) {
13528            isProc = true;
13529            label = _label;
13530            shortLabel = _shortLabel;
13531            pss = _pss;
13532            id = _id;
13533            hasActivities = _hasActivities;
13534        }
13535
13536        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13537            isProc = false;
13538            label = _label;
13539            shortLabel = _shortLabel;
13540            pss = _pss;
13541            id = _id;
13542            hasActivities = false;
13543        }
13544    }
13545
13546    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13547            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13548        if (sort && !isCompact) {
13549            Collections.sort(items, new Comparator<MemItem>() {
13550                @Override
13551                public int compare(MemItem lhs, MemItem rhs) {
13552                    if (lhs.pss < rhs.pss) {
13553                        return 1;
13554                    } else if (lhs.pss > rhs.pss) {
13555                        return -1;
13556                    }
13557                    return 0;
13558                }
13559            });
13560        }
13561
13562        for (int i=0; i<items.size(); i++) {
13563            MemItem mi = items.get(i);
13564            if (!isCompact) {
13565                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13566            } else if (mi.isProc) {
13567                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13568                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13569                pw.println(mi.hasActivities ? ",a" : ",e");
13570            } else {
13571                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13572                pw.println(mi.pss);
13573            }
13574            if (mi.subitems != null) {
13575                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13576                        true, isCompact);
13577            }
13578        }
13579    }
13580
13581    // These are in KB.
13582    static final long[] DUMP_MEM_BUCKETS = new long[] {
13583        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13584        120*1024, 160*1024, 200*1024,
13585        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13586        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13587    };
13588
13589    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13590            boolean stackLike) {
13591        int start = label.lastIndexOf('.');
13592        if (start >= 0) start++;
13593        else start = 0;
13594        int end = label.length();
13595        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13596            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13597                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13598                out.append(bucket);
13599                out.append(stackLike ? "MB." : "MB ");
13600                out.append(label, start, end);
13601                return;
13602            }
13603        }
13604        out.append(memKB/1024);
13605        out.append(stackLike ? "MB." : "MB ");
13606        out.append(label, start, end);
13607    }
13608
13609    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13610            ProcessList.NATIVE_ADJ,
13611            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13612            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13613            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13614            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13615            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13616    };
13617    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13618            "Native",
13619            "System", "Persistent", "Foreground",
13620            "Visible", "Perceptible",
13621            "Heavy Weight", "Backup",
13622            "A Services", "Home",
13623            "Previous", "B Services", "Cached"
13624    };
13625    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13626            "native",
13627            "sys", "pers", "fore",
13628            "vis", "percept",
13629            "heavy", "backup",
13630            "servicea", "home",
13631            "prev", "serviceb", "cached"
13632    };
13633
13634    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13635            long realtime, boolean isCheckinRequest, boolean isCompact) {
13636        if (isCheckinRequest || isCompact) {
13637            // short checkin version
13638            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13639        } else {
13640            pw.println("Applications Memory Usage (kB):");
13641            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13642        }
13643    }
13644
13645    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13646            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13647        boolean dumpDetails = false;
13648        boolean dumpFullDetails = false;
13649        boolean dumpDalvik = false;
13650        boolean oomOnly = false;
13651        boolean isCompact = false;
13652        boolean localOnly = false;
13653
13654        int opti = 0;
13655        while (opti < args.length) {
13656            String opt = args[opti];
13657            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13658                break;
13659            }
13660            opti++;
13661            if ("-a".equals(opt)) {
13662                dumpDetails = true;
13663                dumpFullDetails = true;
13664                dumpDalvik = true;
13665            } else if ("-d".equals(opt)) {
13666                dumpDalvik = true;
13667            } else if ("-c".equals(opt)) {
13668                isCompact = true;
13669            } else if ("--oom".equals(opt)) {
13670                oomOnly = true;
13671            } else if ("--local".equals(opt)) {
13672                localOnly = true;
13673            } else if ("-h".equals(opt)) {
13674                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13675                pw.println("  -a: include all available information for each process.");
13676                pw.println("  -d: include dalvik details when dumping process details.");
13677                pw.println("  -c: dump in a compact machine-parseable representation.");
13678                pw.println("  --oom: only show processes organized by oom adj.");
13679                pw.println("  --local: only collect details locally, don't call process.");
13680                pw.println("If [process] is specified it can be the name or ");
13681                pw.println("pid of a specific process to dump.");
13682                return;
13683            } else {
13684                pw.println("Unknown argument: " + opt + "; use -h for help");
13685            }
13686        }
13687
13688        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13689        long uptime = SystemClock.uptimeMillis();
13690        long realtime = SystemClock.elapsedRealtime();
13691        final long[] tmpLong = new long[1];
13692
13693        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
13694        if (procs == null) {
13695            // No Java processes.  Maybe they want to print a native process.
13696            if (args != null && args.length > opti
13697                    && args[opti].charAt(0) != '-') {
13698                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13699                        = new ArrayList<ProcessCpuTracker.Stats>();
13700                updateCpuStatsNow();
13701                int findPid = -1;
13702                try {
13703                    findPid = Integer.parseInt(args[opti]);
13704                } catch (NumberFormatException e) {
13705                }
13706                synchronized (mProcessCpuTracker) {
13707                    final int N = mProcessCpuTracker.countStats();
13708                    for (int i=0; i<N; i++) {
13709                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13710                        if (st.pid == findPid || (st.baseName != null
13711                                && st.baseName.equals(args[opti]))) {
13712                            nativeProcs.add(st);
13713                        }
13714                    }
13715                }
13716                if (nativeProcs.size() > 0) {
13717                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13718                            isCompact);
13719                    Debug.MemoryInfo mi = null;
13720                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13721                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13722                        final int pid = r.pid;
13723                        if (!isCheckinRequest && dumpDetails) {
13724                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13725                        }
13726                        if (mi == null) {
13727                            mi = new Debug.MemoryInfo();
13728                        }
13729                        if (dumpDetails || (!brief && !oomOnly)) {
13730                            Debug.getMemoryInfo(pid, mi);
13731                        } else {
13732                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13733                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13734                        }
13735                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13736                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13737                        if (isCheckinRequest) {
13738                            pw.println();
13739                        }
13740                    }
13741                    return;
13742                }
13743            }
13744            pw.println("No process found for: " + args[opti]);
13745            return;
13746        }
13747
13748        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13749            dumpDetails = true;
13750        }
13751
13752        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13753
13754        String[] innerArgs = new String[args.length-opti];
13755        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13756
13757        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13758        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13759        long nativePss=0, dalvikPss=0, otherPss=0;
13760        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13761
13762        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13763        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13764                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13765
13766        long totalPss = 0;
13767        long cachedPss = 0;
13768
13769        Debug.MemoryInfo mi = null;
13770        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13771            final ProcessRecord r = procs.get(i);
13772            final IApplicationThread thread;
13773            final int pid;
13774            final int oomAdj;
13775            final boolean hasActivities;
13776            synchronized (this) {
13777                thread = r.thread;
13778                pid = r.pid;
13779                oomAdj = r.getSetAdjWithServices();
13780                hasActivities = r.activities.size() > 0;
13781            }
13782            if (thread != null) {
13783                if (!isCheckinRequest && dumpDetails) {
13784                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13785                }
13786                if (mi == null) {
13787                    mi = new Debug.MemoryInfo();
13788                }
13789                if (dumpDetails || (!brief && !oomOnly)) {
13790                    Debug.getMemoryInfo(pid, mi);
13791                } else {
13792                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13793                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13794                }
13795                if (dumpDetails) {
13796                    if (localOnly) {
13797                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13798                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13799                        if (isCheckinRequest) {
13800                            pw.println();
13801                        }
13802                    } else {
13803                        try {
13804                            pw.flush();
13805                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13806                                    dumpDalvik, innerArgs);
13807                        } catch (RemoteException e) {
13808                            if (!isCheckinRequest) {
13809                                pw.println("Got RemoteException!");
13810                                pw.flush();
13811                            }
13812                        }
13813                    }
13814                }
13815
13816                final long myTotalPss = mi.getTotalPss();
13817                final long myTotalUss = mi.getTotalUss();
13818
13819                synchronized (this) {
13820                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13821                        // Record this for posterity if the process has been stable.
13822                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13823                    }
13824                }
13825
13826                if (!isCheckinRequest && mi != null) {
13827                    totalPss += myTotalPss;
13828                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13829                            (hasActivities ? " / activities)" : ")"),
13830                            r.processName, myTotalPss, pid, hasActivities);
13831                    procMems.add(pssItem);
13832                    procMemsMap.put(pid, pssItem);
13833
13834                    nativePss += mi.nativePss;
13835                    dalvikPss += mi.dalvikPss;
13836                    otherPss += mi.otherPss;
13837                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13838                        long mem = mi.getOtherPss(j);
13839                        miscPss[j] += mem;
13840                        otherPss -= mem;
13841                    }
13842
13843                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13844                        cachedPss += myTotalPss;
13845                    }
13846
13847                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13848                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13849                                || oomIndex == (oomPss.length-1)) {
13850                            oomPss[oomIndex] += myTotalPss;
13851                            if (oomProcs[oomIndex] == null) {
13852                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13853                            }
13854                            oomProcs[oomIndex].add(pssItem);
13855                            break;
13856                        }
13857                    }
13858                }
13859            }
13860        }
13861
13862        long nativeProcTotalPss = 0;
13863
13864        if (!isCheckinRequest && procs.size() > 1) {
13865            // If we are showing aggregations, also look for native processes to
13866            // include so that our aggregations are more accurate.
13867            updateCpuStatsNow();
13868            synchronized (mProcessCpuTracker) {
13869                final int N = mProcessCpuTracker.countStats();
13870                for (int i=0; i<N; i++) {
13871                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13872                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13873                        if (mi == null) {
13874                            mi = new Debug.MemoryInfo();
13875                        }
13876                        if (!brief && !oomOnly) {
13877                            Debug.getMemoryInfo(st.pid, mi);
13878                        } else {
13879                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
13880                            mi.nativePrivateDirty = (int)tmpLong[0];
13881                        }
13882
13883                        final long myTotalPss = mi.getTotalPss();
13884                        totalPss += myTotalPss;
13885                        nativeProcTotalPss += myTotalPss;
13886
13887                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13888                                st.name, myTotalPss, st.pid, false);
13889                        procMems.add(pssItem);
13890
13891                        nativePss += mi.nativePss;
13892                        dalvikPss += mi.dalvikPss;
13893                        otherPss += mi.otherPss;
13894                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13895                            long mem = mi.getOtherPss(j);
13896                            miscPss[j] += mem;
13897                            otherPss -= mem;
13898                        }
13899                        oomPss[0] += myTotalPss;
13900                        if (oomProcs[0] == null) {
13901                            oomProcs[0] = new ArrayList<MemItem>();
13902                        }
13903                        oomProcs[0].add(pssItem);
13904                    }
13905                }
13906            }
13907
13908            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13909
13910            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13911            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13912            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13913            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13914                String label = Debug.MemoryInfo.getOtherLabel(j);
13915                catMems.add(new MemItem(label, label, miscPss[j], j));
13916            }
13917
13918            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13919            for (int j=0; j<oomPss.length; j++) {
13920                if (oomPss[j] != 0) {
13921                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13922                            : DUMP_MEM_OOM_LABEL[j];
13923                    MemItem item = new MemItem(label, label, oomPss[j],
13924                            DUMP_MEM_OOM_ADJ[j]);
13925                    item.subitems = oomProcs[j];
13926                    oomMems.add(item);
13927                }
13928            }
13929
13930            if (!brief && !oomOnly && !isCompact) {
13931                pw.println();
13932                pw.println("Total PSS by process:");
13933                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13934                pw.println();
13935            }
13936            if (!isCompact) {
13937                pw.println("Total PSS by OOM adjustment:");
13938            }
13939            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13940            if (!brief && !oomOnly) {
13941                PrintWriter out = categoryPw != null ? categoryPw : pw;
13942                if (!isCompact) {
13943                    out.println();
13944                    out.println("Total PSS by category:");
13945                }
13946                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13947            }
13948            if (!isCompact) {
13949                pw.println();
13950            }
13951            MemInfoReader memInfo = new MemInfoReader();
13952            memInfo.readMemInfo();
13953            if (nativeProcTotalPss > 0) {
13954                synchronized (this) {
13955                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13956                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13957                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13958                            nativeProcTotalPss);
13959                }
13960            }
13961            if (!brief) {
13962                if (!isCompact) {
13963                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13964                    pw.print(" kB (status ");
13965                    switch (mLastMemoryLevel) {
13966                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13967                            pw.println("normal)");
13968                            break;
13969                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13970                            pw.println("moderate)");
13971                            break;
13972                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13973                            pw.println("low)");
13974                            break;
13975                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13976                            pw.println("critical)");
13977                            break;
13978                        default:
13979                            pw.print(mLastMemoryLevel);
13980                            pw.println(")");
13981                            break;
13982                    }
13983                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13984                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13985                            pw.print(cachedPss); pw.print(" cached pss + ");
13986                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13987                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13988                } else {
13989                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13990                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13991                            + memInfo.getFreeSizeKb()); pw.print(",");
13992                    pw.println(totalPss - cachedPss);
13993                }
13994            }
13995            if (!isCompact) {
13996                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13997                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
13998                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
13999                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14000                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
14001                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
14002                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
14003                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14004                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14005                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
14006                        - memInfo.getSlabSizeKb()); pw.println(" kB");
14007            }
14008            if (!brief) {
14009                if (memInfo.getZramTotalSizeKb() != 0) {
14010                    if (!isCompact) {
14011                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14012                                pw.print(" kB physical used for ");
14013                                pw.print(memInfo.getSwapTotalSizeKb()
14014                                        - memInfo.getSwapFreeSizeKb());
14015                                pw.print(" kB in swap (");
14016                                pw.print(memInfo.getSwapTotalSizeKb());
14017                                pw.println(" kB total swap)");
14018                    } else {
14019                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14020                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14021                                pw.println(memInfo.getSwapFreeSizeKb());
14022                    }
14023                }
14024                final int[] SINGLE_LONG_FORMAT = new int[] {
14025                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14026                };
14027                long[] longOut = new long[1];
14028                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14029                        SINGLE_LONG_FORMAT, null, longOut, null);
14030                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14031                longOut[0] = 0;
14032                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14033                        SINGLE_LONG_FORMAT, null, longOut, null);
14034                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14035                longOut[0] = 0;
14036                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14037                        SINGLE_LONG_FORMAT, null, longOut, null);
14038                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14039                longOut[0] = 0;
14040                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14041                        SINGLE_LONG_FORMAT, null, longOut, null);
14042                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14043                if (!isCompact) {
14044                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
14045                        pw.print("      KSM: "); pw.print(sharing);
14046                                pw.print(" kB saved from shared ");
14047                                pw.print(shared); pw.println(" kB");
14048                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
14049                                pw.print(voltile); pw.println(" kB volatile");
14050                    }
14051                    pw.print("   Tuning: ");
14052                    pw.print(ActivityManager.staticGetMemoryClass());
14053                    pw.print(" (large ");
14054                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14055                    pw.print("), oom ");
14056                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14057                    pw.print(" kB");
14058                    pw.print(", restore limit ");
14059                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14060                    pw.print(" kB");
14061                    if (ActivityManager.isLowRamDeviceStatic()) {
14062                        pw.print(" (low-ram)");
14063                    }
14064                    if (ActivityManager.isHighEndGfx()) {
14065                        pw.print(" (high-end-gfx)");
14066                    }
14067                    pw.println();
14068                } else {
14069                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
14070                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
14071                    pw.println(voltile);
14072                    pw.print("tuning,");
14073                    pw.print(ActivityManager.staticGetMemoryClass());
14074                    pw.print(',');
14075                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14076                    pw.print(',');
14077                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14078                    if (ActivityManager.isLowRamDeviceStatic()) {
14079                        pw.print(",low-ram");
14080                    }
14081                    if (ActivityManager.isHighEndGfx()) {
14082                        pw.print(",high-end-gfx");
14083                    }
14084                    pw.println();
14085                }
14086            }
14087        }
14088    }
14089
14090    /**
14091     * Searches array of arguments for the specified string
14092     * @param args array of argument strings
14093     * @param value value to search for
14094     * @return true if the value is contained in the array
14095     */
14096    private static boolean scanArgs(String[] args, String value) {
14097        if (args != null) {
14098            for (String arg : args) {
14099                if (value.equals(arg)) {
14100                    return true;
14101                }
14102            }
14103        }
14104        return false;
14105    }
14106
14107    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14108            ContentProviderRecord cpr, boolean always) {
14109        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14110
14111        if (!inLaunching || always) {
14112            synchronized (cpr) {
14113                cpr.launchingApp = null;
14114                cpr.notifyAll();
14115            }
14116            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14117            String names[] = cpr.info.authority.split(";");
14118            for (int j = 0; j < names.length; j++) {
14119                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14120            }
14121        }
14122
14123        for (int i=0; i<cpr.connections.size(); i++) {
14124            ContentProviderConnection conn = cpr.connections.get(i);
14125            if (conn.waiting) {
14126                // If this connection is waiting for the provider, then we don't
14127                // need to mess with its process unless we are always removing
14128                // or for some reason the provider is not currently launching.
14129                if (inLaunching && !always) {
14130                    continue;
14131                }
14132            }
14133            ProcessRecord capp = conn.client;
14134            conn.dead = true;
14135            if (conn.stableCount > 0) {
14136                if (!capp.persistent && capp.thread != null
14137                        && capp.pid != 0
14138                        && capp.pid != MY_PID) {
14139                    capp.kill("depends on provider "
14140                            + cpr.name.flattenToShortString()
14141                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14142                }
14143            } else if (capp.thread != null && conn.provider.provider != null) {
14144                try {
14145                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14146                } catch (RemoteException e) {
14147                }
14148                // In the protocol here, we don't expect the client to correctly
14149                // clean up this connection, we'll just remove it.
14150                cpr.connections.remove(i);
14151                conn.client.conProviders.remove(conn);
14152            }
14153        }
14154
14155        if (inLaunching && always) {
14156            mLaunchingProviders.remove(cpr);
14157        }
14158        return inLaunching;
14159    }
14160
14161    /**
14162     * Main code for cleaning up a process when it has gone away.  This is
14163     * called both as a result of the process dying, or directly when stopping
14164     * a process when running in single process mode.
14165     */
14166    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
14167            boolean restarting, boolean allowRestart, int index) {
14168        if (index >= 0) {
14169            removeLruProcessLocked(app);
14170            ProcessList.remove(app.pid);
14171        }
14172
14173        mProcessesToGc.remove(app);
14174        mPendingPssProcesses.remove(app);
14175
14176        // Dismiss any open dialogs.
14177        if (app.crashDialog != null && !app.forceCrashReport) {
14178            app.crashDialog.dismiss();
14179            app.crashDialog = null;
14180        }
14181        if (app.anrDialog != null) {
14182            app.anrDialog.dismiss();
14183            app.anrDialog = null;
14184        }
14185        if (app.waitDialog != null) {
14186            app.waitDialog.dismiss();
14187            app.waitDialog = null;
14188        }
14189
14190        app.crashing = false;
14191        app.notResponding = false;
14192
14193        app.resetPackageList(mProcessStats);
14194        app.unlinkDeathRecipient();
14195        app.makeInactive(mProcessStats);
14196        app.waitingToKill = null;
14197        app.forcingToForeground = null;
14198        updateProcessForegroundLocked(app, false, false);
14199        app.foregroundActivities = false;
14200        app.hasShownUi = false;
14201        app.treatLikeActivity = false;
14202        app.hasAboveClient = false;
14203        app.hasClientActivities = false;
14204
14205        mServices.killServicesLocked(app, allowRestart);
14206
14207        boolean restart = false;
14208
14209        // Remove published content providers.
14210        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14211            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14212            final boolean always = app.bad || !allowRestart;
14213            if (removeDyingProviderLocked(app, cpr, always) || always) {
14214                // We left the provider in the launching list, need to
14215                // restart it.
14216                restart = true;
14217            }
14218
14219            cpr.provider = null;
14220            cpr.proc = null;
14221        }
14222        app.pubProviders.clear();
14223
14224        // Take care of any launching providers waiting for this process.
14225        if (checkAppInLaunchingProvidersLocked(app, false)) {
14226            restart = true;
14227        }
14228
14229        // Unregister from connected content providers.
14230        if (!app.conProviders.isEmpty()) {
14231            for (int i=0; i<app.conProviders.size(); i++) {
14232                ContentProviderConnection conn = app.conProviders.get(i);
14233                conn.provider.connections.remove(conn);
14234            }
14235            app.conProviders.clear();
14236        }
14237
14238        // At this point there may be remaining entries in mLaunchingProviders
14239        // where we were the only one waiting, so they are no longer of use.
14240        // Look for these and clean up if found.
14241        // XXX Commented out for now.  Trying to figure out a way to reproduce
14242        // the actual situation to identify what is actually going on.
14243        if (false) {
14244            for (int i=0; i<mLaunchingProviders.size(); i++) {
14245                ContentProviderRecord cpr = (ContentProviderRecord)
14246                        mLaunchingProviders.get(i);
14247                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14248                    synchronized (cpr) {
14249                        cpr.launchingApp = null;
14250                        cpr.notifyAll();
14251                    }
14252                }
14253            }
14254        }
14255
14256        skipCurrentReceiverLocked(app);
14257
14258        // Unregister any receivers.
14259        for (int i=app.receivers.size()-1; i>=0; i--) {
14260            removeReceiverLocked(app.receivers.valueAt(i));
14261        }
14262        app.receivers.clear();
14263
14264        // If the app is undergoing backup, tell the backup manager about it
14265        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14266            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14267                    + mBackupTarget.appInfo + " died during backup");
14268            try {
14269                IBackupManager bm = IBackupManager.Stub.asInterface(
14270                        ServiceManager.getService(Context.BACKUP_SERVICE));
14271                bm.agentDisconnected(app.info.packageName);
14272            } catch (RemoteException e) {
14273                // can't happen; backup manager is local
14274            }
14275        }
14276
14277        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14278            ProcessChangeItem item = mPendingProcessChanges.get(i);
14279            if (item.pid == app.pid) {
14280                mPendingProcessChanges.remove(i);
14281                mAvailProcessChanges.add(item);
14282            }
14283        }
14284        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14285
14286        // If the caller is restarting this app, then leave it in its
14287        // current lists and let the caller take care of it.
14288        if (restarting) {
14289            return;
14290        }
14291
14292        if (!app.persistent || app.isolated) {
14293            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14294                    "Removing non-persistent process during cleanup: " + app);
14295            mProcessNames.remove(app.processName, app.uid);
14296            mIsolatedProcesses.remove(app.uid);
14297            if (mHeavyWeightProcess == app) {
14298                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14299                        mHeavyWeightProcess.userId, 0));
14300                mHeavyWeightProcess = null;
14301            }
14302        } else if (!app.removed) {
14303            // This app is persistent, so we need to keep its record around.
14304            // If it is not already on the pending app list, add it there
14305            // and start a new process for it.
14306            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14307                mPersistentStartingProcesses.add(app);
14308                restart = true;
14309            }
14310        }
14311        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14312                "Clean-up removing on hold: " + app);
14313        mProcessesOnHold.remove(app);
14314
14315        if (app == mHomeProcess) {
14316            mHomeProcess = null;
14317        }
14318        if (app == mPreviousProcess) {
14319            mPreviousProcess = null;
14320        }
14321
14322        if (restart && !app.isolated) {
14323            // We have components that still need to be running in the
14324            // process, so re-launch it.
14325            mProcessNames.put(app.processName, app.uid, app);
14326            startProcessLocked(app, "restart", app.processName);
14327        } else if (app.pid > 0 && app.pid != MY_PID) {
14328            // Goodbye!
14329            boolean removed;
14330            synchronized (mPidsSelfLocked) {
14331                mPidsSelfLocked.remove(app.pid);
14332                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14333            }
14334            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14335            if (app.isolated) {
14336                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14337            }
14338            app.setPid(0);
14339        }
14340    }
14341
14342    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14343        // Look through the content providers we are waiting to have launched,
14344        // and if any run in this process then either schedule a restart of
14345        // the process or kill the client waiting for it if this process has
14346        // gone bad.
14347        int NL = mLaunchingProviders.size();
14348        boolean restart = false;
14349        for (int i=0; i<NL; i++) {
14350            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14351            if (cpr.launchingApp == app) {
14352                if (!alwaysBad && !app.bad) {
14353                    restart = true;
14354                } else {
14355                    removeDyingProviderLocked(app, cpr, true);
14356                    // cpr should have been removed from mLaunchingProviders
14357                    NL = mLaunchingProviders.size();
14358                    i--;
14359                }
14360            }
14361        }
14362        return restart;
14363    }
14364
14365    // =========================================================
14366    // SERVICES
14367    // =========================================================
14368
14369    @Override
14370    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14371            int flags) {
14372        enforceNotIsolatedCaller("getServices");
14373        synchronized (this) {
14374            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14375        }
14376    }
14377
14378    @Override
14379    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14380        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14381        synchronized (this) {
14382            return mServices.getRunningServiceControlPanelLocked(name);
14383        }
14384    }
14385
14386    @Override
14387    public ComponentName startService(IApplicationThread caller, Intent service,
14388            String resolvedType, int userId) {
14389        enforceNotIsolatedCaller("startService");
14390        // Refuse possible leaked file descriptors
14391        if (service != null && service.hasFileDescriptors() == true) {
14392            throw new IllegalArgumentException("File descriptors passed in Intent");
14393        }
14394
14395        if (DEBUG_SERVICE)
14396            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14397        synchronized(this) {
14398            final int callingPid = Binder.getCallingPid();
14399            final int callingUid = Binder.getCallingUid();
14400            final long origId = Binder.clearCallingIdentity();
14401            ComponentName res = mServices.startServiceLocked(caller, service,
14402                    resolvedType, callingPid, callingUid, userId);
14403            Binder.restoreCallingIdentity(origId);
14404            return res;
14405        }
14406    }
14407
14408    ComponentName startServiceInPackage(int uid,
14409            Intent service, String resolvedType, int userId) {
14410        synchronized(this) {
14411            if (DEBUG_SERVICE)
14412                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14413            final long origId = Binder.clearCallingIdentity();
14414            ComponentName res = mServices.startServiceLocked(null, service,
14415                    resolvedType, -1, uid, userId);
14416            Binder.restoreCallingIdentity(origId);
14417            return res;
14418        }
14419    }
14420
14421    @Override
14422    public int stopService(IApplicationThread caller, Intent service,
14423            String resolvedType, int userId) {
14424        enforceNotIsolatedCaller("stopService");
14425        // Refuse possible leaked file descriptors
14426        if (service != null && service.hasFileDescriptors() == true) {
14427            throw new IllegalArgumentException("File descriptors passed in Intent");
14428        }
14429
14430        synchronized(this) {
14431            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14432        }
14433    }
14434
14435    @Override
14436    public IBinder peekService(Intent service, String resolvedType) {
14437        enforceNotIsolatedCaller("peekService");
14438        // Refuse possible leaked file descriptors
14439        if (service != null && service.hasFileDescriptors() == true) {
14440            throw new IllegalArgumentException("File descriptors passed in Intent");
14441        }
14442        synchronized(this) {
14443            return mServices.peekServiceLocked(service, resolvedType);
14444        }
14445    }
14446
14447    @Override
14448    public boolean stopServiceToken(ComponentName className, IBinder token,
14449            int startId) {
14450        synchronized(this) {
14451            return mServices.stopServiceTokenLocked(className, token, startId);
14452        }
14453    }
14454
14455    @Override
14456    public void setServiceForeground(ComponentName className, IBinder token,
14457            int id, Notification notification, boolean removeNotification) {
14458        synchronized(this) {
14459            mServices.setServiceForegroundLocked(className, token, id, notification,
14460                    removeNotification);
14461        }
14462    }
14463
14464    @Override
14465    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14466            boolean requireFull, String name, String callerPackage) {
14467        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14468                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14469    }
14470
14471    int unsafeConvertIncomingUser(int userId) {
14472        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14473                ? mCurrentUserId : userId;
14474    }
14475
14476    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14477            int allowMode, String name, String callerPackage) {
14478        final int callingUserId = UserHandle.getUserId(callingUid);
14479        if (callingUserId == userId) {
14480            return userId;
14481        }
14482
14483        // Note that we may be accessing mCurrentUserId outside of a lock...
14484        // shouldn't be a big deal, if this is being called outside
14485        // of a locked context there is intrinsically a race with
14486        // the value the caller will receive and someone else changing it.
14487        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14488        // we will switch to the calling user if access to the current user fails.
14489        int targetUserId = unsafeConvertIncomingUser(userId);
14490
14491        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14492            final boolean allow;
14493            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14494                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14495                // If the caller has this permission, they always pass go.  And collect $200.
14496                allow = true;
14497            } else if (allowMode == ALLOW_FULL_ONLY) {
14498                // We require full access, sucks to be you.
14499                allow = false;
14500            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14501                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14502                // If the caller does not have either permission, they are always doomed.
14503                allow = false;
14504            } else if (allowMode == ALLOW_NON_FULL) {
14505                // We are blanket allowing non-full access, you lucky caller!
14506                allow = true;
14507            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14508                // We may or may not allow this depending on whether the two users are
14509                // in the same profile.
14510                synchronized (mUserProfileGroupIdsSelfLocked) {
14511                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14512                            UserInfo.NO_PROFILE_GROUP_ID);
14513                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14514                            UserInfo.NO_PROFILE_GROUP_ID);
14515                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14516                            && callingProfile == targetProfile;
14517                }
14518            } else {
14519                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14520            }
14521            if (!allow) {
14522                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14523                    // In this case, they would like to just execute as their
14524                    // owner user instead of failing.
14525                    targetUserId = callingUserId;
14526                } else {
14527                    StringBuilder builder = new StringBuilder(128);
14528                    builder.append("Permission Denial: ");
14529                    builder.append(name);
14530                    if (callerPackage != null) {
14531                        builder.append(" from ");
14532                        builder.append(callerPackage);
14533                    }
14534                    builder.append(" asks to run as user ");
14535                    builder.append(userId);
14536                    builder.append(" but is calling from user ");
14537                    builder.append(UserHandle.getUserId(callingUid));
14538                    builder.append("; this requires ");
14539                    builder.append(INTERACT_ACROSS_USERS_FULL);
14540                    if (allowMode != ALLOW_FULL_ONLY) {
14541                        builder.append(" or ");
14542                        builder.append(INTERACT_ACROSS_USERS);
14543                    }
14544                    String msg = builder.toString();
14545                    Slog.w(TAG, msg);
14546                    throw new SecurityException(msg);
14547                }
14548            }
14549        }
14550        if (!allowAll && targetUserId < 0) {
14551            throw new IllegalArgumentException(
14552                    "Call does not support special user #" + targetUserId);
14553        }
14554        return targetUserId;
14555    }
14556
14557    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14558            String className, int flags) {
14559        boolean result = false;
14560        // For apps that don't have pre-defined UIDs, check for permission
14561        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14562            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14563                if (ActivityManager.checkUidPermission(
14564                        INTERACT_ACROSS_USERS,
14565                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14566                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14567                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14568                            + " requests FLAG_SINGLE_USER, but app does not hold "
14569                            + INTERACT_ACROSS_USERS;
14570                    Slog.w(TAG, msg);
14571                    throw new SecurityException(msg);
14572                }
14573                // Permission passed
14574                result = true;
14575            }
14576        } else if ("system".equals(componentProcessName)) {
14577            result = true;
14578        } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14579                && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14580            // Phone app is allowed to export singleuser providers.
14581            result = true;
14582        } else {
14583            // App with pre-defined UID, check if it's a persistent app
14584            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14585        }
14586        if (DEBUG_MU) {
14587            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14588                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14589        }
14590        return result;
14591    }
14592
14593    /**
14594     * Checks to see if the caller is in the same app as the singleton
14595     * component, or the component is in a special app. It allows special apps
14596     * to export singleton components but prevents exporting singleton
14597     * components for regular apps.
14598     */
14599    boolean isValidSingletonCall(int callingUid, int componentUid) {
14600        int componentAppId = UserHandle.getAppId(componentUid);
14601        return UserHandle.isSameApp(callingUid, componentUid)
14602                || componentAppId == Process.SYSTEM_UID
14603                || componentAppId == Process.PHONE_UID
14604                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14605                        == PackageManager.PERMISSION_GRANTED;
14606    }
14607
14608    public int bindService(IApplicationThread caller, IBinder token,
14609            Intent service, String resolvedType,
14610            IServiceConnection connection, int flags, int userId) {
14611        enforceNotIsolatedCaller("bindService");
14612        // Refuse possible leaked file descriptors
14613        if (service != null && service.hasFileDescriptors() == true) {
14614            throw new IllegalArgumentException("File descriptors passed in Intent");
14615        }
14616
14617        synchronized(this) {
14618            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14619                    connection, flags, userId);
14620        }
14621    }
14622
14623    public boolean unbindService(IServiceConnection connection) {
14624        synchronized (this) {
14625            return mServices.unbindServiceLocked(connection);
14626        }
14627    }
14628
14629    public void publishService(IBinder token, Intent intent, IBinder service) {
14630        // Refuse possible leaked file descriptors
14631        if (intent != null && intent.hasFileDescriptors() == true) {
14632            throw new IllegalArgumentException("File descriptors passed in Intent");
14633        }
14634
14635        synchronized(this) {
14636            if (!(token instanceof ServiceRecord)) {
14637                throw new IllegalArgumentException("Invalid service token");
14638            }
14639            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14640        }
14641    }
14642
14643    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14644        // Refuse possible leaked file descriptors
14645        if (intent != null && intent.hasFileDescriptors() == true) {
14646            throw new IllegalArgumentException("File descriptors passed in Intent");
14647        }
14648
14649        synchronized(this) {
14650            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14651        }
14652    }
14653
14654    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14655        synchronized(this) {
14656            if (!(token instanceof ServiceRecord)) {
14657                throw new IllegalArgumentException("Invalid service token");
14658            }
14659            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14660        }
14661    }
14662
14663    // =========================================================
14664    // BACKUP AND RESTORE
14665    // =========================================================
14666
14667    // Cause the target app to be launched if necessary and its backup agent
14668    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14669    // activity manager to announce its creation.
14670    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14671        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14672        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14673
14674        synchronized(this) {
14675            // !!! TODO: currently no check here that we're already bound
14676            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14677            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14678            synchronized (stats) {
14679                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14680            }
14681
14682            // Backup agent is now in use, its package can't be stopped.
14683            try {
14684                AppGlobals.getPackageManager().setPackageStoppedState(
14685                        app.packageName, false, UserHandle.getUserId(app.uid));
14686            } catch (RemoteException e) {
14687            } catch (IllegalArgumentException e) {
14688                Slog.w(TAG, "Failed trying to unstop package "
14689                        + app.packageName + ": " + e);
14690            }
14691
14692            BackupRecord r = new BackupRecord(ss, app, backupMode);
14693            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14694                    ? new ComponentName(app.packageName, app.backupAgentName)
14695                    : new ComponentName("android", "FullBackupAgent");
14696            // startProcessLocked() returns existing proc's record if it's already running
14697            ProcessRecord proc = startProcessLocked(app.processName, app,
14698                    false, 0, "backup", hostingName, false, false, false);
14699            if (proc == null) {
14700                Slog.e(TAG, "Unable to start backup agent process " + r);
14701                return false;
14702            }
14703
14704            r.app = proc;
14705            mBackupTarget = r;
14706            mBackupAppName = app.packageName;
14707
14708            // Try not to kill the process during backup
14709            updateOomAdjLocked(proc);
14710
14711            // If the process is already attached, schedule the creation of the backup agent now.
14712            // If it is not yet live, this will be done when it attaches to the framework.
14713            if (proc.thread != null) {
14714                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14715                try {
14716                    proc.thread.scheduleCreateBackupAgent(app,
14717                            compatibilityInfoForPackageLocked(app), backupMode);
14718                } catch (RemoteException e) {
14719                    // Will time out on the backup manager side
14720                }
14721            } else {
14722                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14723            }
14724            // Invariants: at this point, the target app process exists and the application
14725            // is either already running or in the process of coming up.  mBackupTarget and
14726            // mBackupAppName describe the app, so that when it binds back to the AM we
14727            // know that it's scheduled for a backup-agent operation.
14728        }
14729
14730        return true;
14731    }
14732
14733    @Override
14734    public void clearPendingBackup() {
14735        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14736        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14737
14738        synchronized (this) {
14739            mBackupTarget = null;
14740            mBackupAppName = null;
14741        }
14742    }
14743
14744    // A backup agent has just come up
14745    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14746        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14747                + " = " + agent);
14748
14749        synchronized(this) {
14750            if (!agentPackageName.equals(mBackupAppName)) {
14751                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14752                return;
14753            }
14754        }
14755
14756        long oldIdent = Binder.clearCallingIdentity();
14757        try {
14758            IBackupManager bm = IBackupManager.Stub.asInterface(
14759                    ServiceManager.getService(Context.BACKUP_SERVICE));
14760            bm.agentConnected(agentPackageName, agent);
14761        } catch (RemoteException e) {
14762            // can't happen; the backup manager service is local
14763        } catch (Exception e) {
14764            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14765            e.printStackTrace();
14766        } finally {
14767            Binder.restoreCallingIdentity(oldIdent);
14768        }
14769    }
14770
14771    // done with this agent
14772    public void unbindBackupAgent(ApplicationInfo appInfo) {
14773        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14774        if (appInfo == null) {
14775            Slog.w(TAG, "unbind backup agent for null app");
14776            return;
14777        }
14778
14779        synchronized(this) {
14780            try {
14781                if (mBackupAppName == null) {
14782                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14783                    return;
14784                }
14785
14786                if (!mBackupAppName.equals(appInfo.packageName)) {
14787                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14788                    return;
14789                }
14790
14791                // Not backing this app up any more; reset its OOM adjustment
14792                final ProcessRecord proc = mBackupTarget.app;
14793                updateOomAdjLocked(proc);
14794
14795                // If the app crashed during backup, 'thread' will be null here
14796                if (proc.thread != null) {
14797                    try {
14798                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14799                                compatibilityInfoForPackageLocked(appInfo));
14800                    } catch (Exception e) {
14801                        Slog.e(TAG, "Exception when unbinding backup agent:");
14802                        e.printStackTrace();
14803                    }
14804                }
14805            } finally {
14806                mBackupTarget = null;
14807                mBackupAppName = null;
14808            }
14809        }
14810    }
14811    // =========================================================
14812    // BROADCASTS
14813    // =========================================================
14814
14815    private final List getStickiesLocked(String action, IntentFilter filter,
14816            List cur, int userId) {
14817        final ContentResolver resolver = mContext.getContentResolver();
14818        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14819        if (stickies == null) {
14820            return cur;
14821        }
14822        final ArrayList<Intent> list = stickies.get(action);
14823        if (list == null) {
14824            return cur;
14825        }
14826        int N = list.size();
14827        for (int i=0; i<N; i++) {
14828            Intent intent = list.get(i);
14829            if (filter.match(resolver, intent, true, TAG) >= 0) {
14830                if (cur == null) {
14831                    cur = new ArrayList<Intent>();
14832                }
14833                cur.add(intent);
14834            }
14835        }
14836        return cur;
14837    }
14838
14839    boolean isPendingBroadcastProcessLocked(int pid) {
14840        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
14841                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
14842    }
14843
14844    void skipPendingBroadcastLocked(int pid) {
14845            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
14846            for (BroadcastQueue queue : mBroadcastQueues) {
14847                queue.skipPendingBroadcastLocked(pid);
14848            }
14849    }
14850
14851    // The app just attached; send any pending broadcasts that it should receive
14852    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14853        boolean didSomething = false;
14854        for (BroadcastQueue queue : mBroadcastQueues) {
14855            didSomething |= queue.sendPendingBroadcastsLocked(app);
14856        }
14857        return didSomething;
14858    }
14859
14860    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14861            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
14862        enforceNotIsolatedCaller("registerReceiver");
14863        int callingUid;
14864        int callingPid;
14865        synchronized(this) {
14866            ProcessRecord callerApp = null;
14867            if (caller != null) {
14868                callerApp = getRecordForAppLocked(caller);
14869                if (callerApp == null) {
14870                    throw new SecurityException(
14871                            "Unable to find app for caller " + caller
14872                            + " (pid=" + Binder.getCallingPid()
14873                            + ") when registering receiver " + receiver);
14874                }
14875                if (callerApp.info.uid != Process.SYSTEM_UID &&
14876                        !callerApp.pkgList.containsKey(callerPackage) &&
14877                        !"android".equals(callerPackage)) {
14878                    throw new SecurityException("Given caller package " + callerPackage
14879                            + " is not running in process " + callerApp);
14880                }
14881                callingUid = callerApp.info.uid;
14882                callingPid = callerApp.pid;
14883            } else {
14884                callerPackage = null;
14885                callingUid = Binder.getCallingUid();
14886                callingPid = Binder.getCallingPid();
14887            }
14888
14889            userId = this.handleIncomingUser(callingPid, callingUid, userId,
14890                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
14891
14892            List allSticky = null;
14893
14894            // Look for any matching sticky broadcasts...
14895            Iterator actions = filter.actionsIterator();
14896            if (actions != null) {
14897                while (actions.hasNext()) {
14898                    String action = (String)actions.next();
14899                    allSticky = getStickiesLocked(action, filter, allSticky,
14900                            UserHandle.USER_ALL);
14901                    allSticky = getStickiesLocked(action, filter, allSticky,
14902                            UserHandle.getUserId(callingUid));
14903                }
14904            } else {
14905                allSticky = getStickiesLocked(null, filter, allSticky,
14906                        UserHandle.USER_ALL);
14907                allSticky = getStickiesLocked(null, filter, allSticky,
14908                        UserHandle.getUserId(callingUid));
14909            }
14910
14911            // The first sticky in the list is returned directly back to
14912            // the client.
14913            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14914
14915            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14916                    + ": " + sticky);
14917
14918            if (receiver == null) {
14919                return sticky;
14920            }
14921
14922            ReceiverList rl
14923                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14924            if (rl == null) {
14925                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14926                        userId, receiver);
14927                if (rl.app != null) {
14928                    rl.app.receivers.add(rl);
14929                } else {
14930                    try {
14931                        receiver.asBinder().linkToDeath(rl, 0);
14932                    } catch (RemoteException e) {
14933                        return sticky;
14934                    }
14935                    rl.linkedToDeath = true;
14936                }
14937                mRegisteredReceivers.put(receiver.asBinder(), rl);
14938            } else if (rl.uid != callingUid) {
14939                throw new IllegalArgumentException(
14940                        "Receiver requested to register for uid " + callingUid
14941                        + " was previously registered for uid " + rl.uid);
14942            } else if (rl.pid != callingPid) {
14943                throw new IllegalArgumentException(
14944                        "Receiver requested to register for pid " + callingPid
14945                        + " was previously registered for pid " + rl.pid);
14946            } else if (rl.userId != userId) {
14947                throw new IllegalArgumentException(
14948                        "Receiver requested to register for user " + userId
14949                        + " was previously registered for user " + rl.userId);
14950            }
14951            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14952                    permission, callingUid, userId);
14953            rl.add(bf);
14954            if (!bf.debugCheck()) {
14955                Slog.w(TAG, "==> For Dynamic broadast");
14956            }
14957            mReceiverResolver.addFilter(bf);
14958
14959            // Enqueue broadcasts for all existing stickies that match
14960            // this filter.
14961            if (allSticky != null) {
14962                ArrayList receivers = new ArrayList();
14963                receivers.add(bf);
14964
14965                int N = allSticky.size();
14966                for (int i=0; i<N; i++) {
14967                    Intent intent = (Intent)allSticky.get(i);
14968                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14969                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14970                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14971                            null, null, false, true, true, -1);
14972                    queue.enqueueParallelBroadcastLocked(r);
14973                    queue.scheduleBroadcastsLocked();
14974                }
14975            }
14976
14977            return sticky;
14978        }
14979    }
14980
14981    public void unregisterReceiver(IIntentReceiver receiver) {
14982        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14983
14984        final long origId = Binder.clearCallingIdentity();
14985        try {
14986            boolean doTrim = false;
14987
14988            synchronized(this) {
14989                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14990                if (rl != null) {
14991                    if (rl.curBroadcast != null) {
14992                        BroadcastRecord r = rl.curBroadcast;
14993                        final boolean doNext = finishReceiverLocked(
14994                                receiver.asBinder(), r.resultCode, r.resultData,
14995                                r.resultExtras, r.resultAbort);
14996                        if (doNext) {
14997                            doTrim = true;
14998                            r.queue.processNextBroadcast(false);
14999                        }
15000                    }
15001
15002                    if (rl.app != null) {
15003                        rl.app.receivers.remove(rl);
15004                    }
15005                    removeReceiverLocked(rl);
15006                    if (rl.linkedToDeath) {
15007                        rl.linkedToDeath = false;
15008                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15009                    }
15010                }
15011            }
15012
15013            // If we actually concluded any broadcasts, we might now be able
15014            // to trim the recipients' apps from our working set
15015            if (doTrim) {
15016                trimApplications();
15017                return;
15018            }
15019
15020        } finally {
15021            Binder.restoreCallingIdentity(origId);
15022        }
15023    }
15024
15025    void removeReceiverLocked(ReceiverList rl) {
15026        mRegisteredReceivers.remove(rl.receiver.asBinder());
15027        int N = rl.size();
15028        for (int i=0; i<N; i++) {
15029            mReceiverResolver.removeFilter(rl.get(i));
15030        }
15031    }
15032
15033    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15034        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15035            ProcessRecord r = mLruProcesses.get(i);
15036            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15037                try {
15038                    r.thread.dispatchPackageBroadcast(cmd, packages);
15039                } catch (RemoteException ex) {
15040                }
15041            }
15042        }
15043    }
15044
15045    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15046            int[] users) {
15047        List<ResolveInfo> receivers = null;
15048        try {
15049            HashSet<ComponentName> singleUserReceivers = null;
15050            boolean scannedFirstReceivers = false;
15051            for (int user : users) {
15052                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15053                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15054                if (user != 0 && newReceivers != null) {
15055                    // If this is not the primary user, we need to check for
15056                    // any receivers that should be filtered out.
15057                    for (int i=0; i<newReceivers.size(); i++) {
15058                        ResolveInfo ri = newReceivers.get(i);
15059                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15060                            newReceivers.remove(i);
15061                            i--;
15062                        }
15063                    }
15064                }
15065                if (newReceivers != null && newReceivers.size() == 0) {
15066                    newReceivers = null;
15067                }
15068                if (receivers == null) {
15069                    receivers = newReceivers;
15070                } else if (newReceivers != null) {
15071                    // We need to concatenate the additional receivers
15072                    // found with what we have do far.  This would be easy,
15073                    // but we also need to de-dup any receivers that are
15074                    // singleUser.
15075                    if (!scannedFirstReceivers) {
15076                        // Collect any single user receivers we had already retrieved.
15077                        scannedFirstReceivers = true;
15078                        for (int i=0; i<receivers.size(); i++) {
15079                            ResolveInfo ri = receivers.get(i);
15080                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15081                                ComponentName cn = new ComponentName(
15082                                        ri.activityInfo.packageName, ri.activityInfo.name);
15083                                if (singleUserReceivers == null) {
15084                                    singleUserReceivers = new HashSet<ComponentName>();
15085                                }
15086                                singleUserReceivers.add(cn);
15087                            }
15088                        }
15089                    }
15090                    // Add the new results to the existing results, tracking
15091                    // and de-dupping single user receivers.
15092                    for (int i=0; i<newReceivers.size(); i++) {
15093                        ResolveInfo ri = newReceivers.get(i);
15094                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15095                            ComponentName cn = new ComponentName(
15096                                    ri.activityInfo.packageName, ri.activityInfo.name);
15097                            if (singleUserReceivers == null) {
15098                                singleUserReceivers = new HashSet<ComponentName>();
15099                            }
15100                            if (!singleUserReceivers.contains(cn)) {
15101                                singleUserReceivers.add(cn);
15102                                receivers.add(ri);
15103                            }
15104                        } else {
15105                            receivers.add(ri);
15106                        }
15107                    }
15108                }
15109            }
15110        } catch (RemoteException ex) {
15111            // pm is in same process, this will never happen.
15112        }
15113        return receivers;
15114    }
15115
15116    private final int broadcastIntentLocked(ProcessRecord callerApp,
15117            String callerPackage, Intent intent, String resolvedType,
15118            IIntentReceiver resultTo, int resultCode, String resultData,
15119            Bundle map, String requiredPermission, int appOp,
15120            boolean ordered, boolean sticky, int callingPid, int callingUid,
15121            int userId) {
15122        intent = new Intent(intent);
15123
15124        // By default broadcasts do not go to stopped apps.
15125        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15126
15127        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15128            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15129            + " ordered=" + ordered + " userid=" + userId);
15130        if ((resultTo != null) && !ordered) {
15131            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15132        }
15133
15134        userId = handleIncomingUser(callingPid, callingUid, userId,
15135                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15136
15137        // Make sure that the user who is receiving this broadcast is started.
15138        // If not, we will just skip it.
15139
15140
15141        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15142            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15143                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15144                Slog.w(TAG, "Skipping broadcast of " + intent
15145                        + ": user " + userId + " is stopped");
15146                return ActivityManager.BROADCAST_SUCCESS;
15147            }
15148        }
15149
15150        /*
15151         * Prevent non-system code (defined here to be non-persistent
15152         * processes) from sending protected broadcasts.
15153         */
15154        int callingAppId = UserHandle.getAppId(callingUid);
15155        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15156            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15157            || callingAppId == Process.NFC_UID || callingUid == 0) {
15158            // Always okay.
15159        } else if (callerApp == null || !callerApp.persistent) {
15160            try {
15161                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15162                        intent.getAction())) {
15163                    String msg = "Permission Denial: not allowed to send broadcast "
15164                            + intent.getAction() + " from pid="
15165                            + callingPid + ", uid=" + callingUid;
15166                    Slog.w(TAG, msg);
15167                    throw new SecurityException(msg);
15168                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15169                    // Special case for compatibility: we don't want apps to send this,
15170                    // but historically it has not been protected and apps may be using it
15171                    // to poke their own app widget.  So, instead of making it protected,
15172                    // just limit it to the caller.
15173                    if (callerApp == null) {
15174                        String msg = "Permission Denial: not allowed to send broadcast "
15175                                + intent.getAction() + " from unknown caller.";
15176                        Slog.w(TAG, msg);
15177                        throw new SecurityException(msg);
15178                    } else if (intent.getComponent() != null) {
15179                        // They are good enough to send to an explicit component...  verify
15180                        // it is being sent to the calling app.
15181                        if (!intent.getComponent().getPackageName().equals(
15182                                callerApp.info.packageName)) {
15183                            String msg = "Permission Denial: not allowed to send broadcast "
15184                                    + intent.getAction() + " to "
15185                                    + intent.getComponent().getPackageName() + " from "
15186                                    + callerApp.info.packageName;
15187                            Slog.w(TAG, msg);
15188                            throw new SecurityException(msg);
15189                        }
15190                    } else {
15191                        // Limit broadcast to their own package.
15192                        intent.setPackage(callerApp.info.packageName);
15193                    }
15194                }
15195            } catch (RemoteException e) {
15196                Slog.w(TAG, "Remote exception", e);
15197                return ActivityManager.BROADCAST_SUCCESS;
15198            }
15199        }
15200
15201        // Handle special intents: if this broadcast is from the package
15202        // manager about a package being removed, we need to remove all of
15203        // its activities from the history stack.
15204        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15205                intent.getAction());
15206        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15207                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15208                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15209                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15210                || uidRemoved) {
15211            if (checkComponentPermission(
15212                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15213                    callingPid, callingUid, -1, true)
15214                    == PackageManager.PERMISSION_GRANTED) {
15215                if (uidRemoved) {
15216                    final Bundle intentExtras = intent.getExtras();
15217                    final int uid = intentExtras != null
15218                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15219                    if (uid >= 0) {
15220                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15221                        synchronized (bs) {
15222                            bs.removeUidStatsLocked(uid);
15223                        }
15224                        mAppOpsService.uidRemoved(uid);
15225                    }
15226                } else {
15227                    // If resources are unavailable just force stop all
15228                    // those packages and flush the attribute cache as well.
15229                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15230                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15231                        if (list != null && (list.length > 0)) {
15232                            for (String pkg : list) {
15233                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15234                                        "storage unmount");
15235                            }
15236                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15237                            sendPackageBroadcastLocked(
15238                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15239                        }
15240                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15241                            intent.getAction())) {
15242                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15243                    } else {
15244                        Uri data = intent.getData();
15245                        String ssp;
15246                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15247                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15248                                    intent.getAction());
15249                            boolean fullUninstall = removed &&
15250                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15251                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15252                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15253                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15254                                        false, fullUninstall, userId,
15255                                        removed ? "pkg removed" : "pkg changed");
15256                            }
15257                            if (removed) {
15258                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15259                                        new String[] {ssp}, userId);
15260                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15261                                    mAppOpsService.packageRemoved(
15262                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15263
15264                                    // Remove all permissions granted from/to this package
15265                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15266                                }
15267                            }
15268                        }
15269                    }
15270                }
15271            } else {
15272                String msg = "Permission Denial: " + intent.getAction()
15273                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15274                        + ", uid=" + callingUid + ")"
15275                        + " requires "
15276                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15277                Slog.w(TAG, msg);
15278                throw new SecurityException(msg);
15279            }
15280
15281        // Special case for adding a package: by default turn on compatibility
15282        // mode.
15283        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15284            Uri data = intent.getData();
15285            String ssp;
15286            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15287                mCompatModePackages.handlePackageAddedLocked(ssp,
15288                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15289            }
15290        }
15291
15292        /*
15293         * If this is the time zone changed action, queue up a message that will reset the timezone
15294         * of all currently running processes. This message will get queued up before the broadcast
15295         * happens.
15296         */
15297        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15298            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15299        }
15300
15301        /*
15302         * If the user set the time, let all running processes know.
15303         */
15304        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15305            final int is24Hour = intent.getBooleanExtra(
15306                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15307            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15308            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15309            synchronized (stats) {
15310                stats.noteCurrentTimeChangedLocked();
15311            }
15312        }
15313
15314        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15315            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15316        }
15317
15318        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15319            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15320            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15321        }
15322
15323        // Add to the sticky list if requested.
15324        if (sticky) {
15325            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15326                    callingPid, callingUid)
15327                    != PackageManager.PERMISSION_GRANTED) {
15328                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15329                        + callingPid + ", uid=" + callingUid
15330                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15331                Slog.w(TAG, msg);
15332                throw new SecurityException(msg);
15333            }
15334            if (requiredPermission != null) {
15335                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15336                        + " and enforce permission " + requiredPermission);
15337                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15338            }
15339            if (intent.getComponent() != null) {
15340                throw new SecurityException(
15341                        "Sticky broadcasts can't target a specific component");
15342            }
15343            // We use userId directly here, since the "all" target is maintained
15344            // as a separate set of sticky broadcasts.
15345            if (userId != UserHandle.USER_ALL) {
15346                // But first, if this is not a broadcast to all users, then
15347                // make sure it doesn't conflict with an existing broadcast to
15348                // all users.
15349                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15350                        UserHandle.USER_ALL);
15351                if (stickies != null) {
15352                    ArrayList<Intent> list = stickies.get(intent.getAction());
15353                    if (list != null) {
15354                        int N = list.size();
15355                        int i;
15356                        for (i=0; i<N; i++) {
15357                            if (intent.filterEquals(list.get(i))) {
15358                                throw new IllegalArgumentException(
15359                                        "Sticky broadcast " + intent + " for user "
15360                                        + userId + " conflicts with existing global broadcast");
15361                            }
15362                        }
15363                    }
15364                }
15365            }
15366            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15367            if (stickies == null) {
15368                stickies = new ArrayMap<String, ArrayList<Intent>>();
15369                mStickyBroadcasts.put(userId, stickies);
15370            }
15371            ArrayList<Intent> list = stickies.get(intent.getAction());
15372            if (list == null) {
15373                list = new ArrayList<Intent>();
15374                stickies.put(intent.getAction(), list);
15375            }
15376            int N = list.size();
15377            int i;
15378            for (i=0; i<N; i++) {
15379                if (intent.filterEquals(list.get(i))) {
15380                    // This sticky already exists, replace it.
15381                    list.set(i, new Intent(intent));
15382                    break;
15383                }
15384            }
15385            if (i >= N) {
15386                list.add(new Intent(intent));
15387            }
15388        }
15389
15390        int[] users;
15391        if (userId == UserHandle.USER_ALL) {
15392            // Caller wants broadcast to go to all started users.
15393            users = mStartedUserArray;
15394        } else {
15395            // Caller wants broadcast to go to one specific user.
15396            users = new int[] {userId};
15397        }
15398
15399        // Figure out who all will receive this broadcast.
15400        List receivers = null;
15401        List<BroadcastFilter> registeredReceivers = null;
15402        // Need to resolve the intent to interested receivers...
15403        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15404                 == 0) {
15405            receivers = collectReceiverComponents(intent, resolvedType, users);
15406        }
15407        if (intent.getComponent() == null) {
15408            registeredReceivers = mReceiverResolver.queryIntent(intent,
15409                    resolvedType, false, userId);
15410        }
15411
15412        final boolean replacePending =
15413                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15414
15415        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15416                + " replacePending=" + replacePending);
15417
15418        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15419        if (!ordered && NR > 0) {
15420            // If we are not serializing this broadcast, then send the
15421            // registered receivers separately so they don't wait for the
15422            // components to be launched.
15423            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15424            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15425                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15426                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15427                    ordered, sticky, false, userId);
15428            if (DEBUG_BROADCAST) Slog.v(
15429                    TAG, "Enqueueing parallel broadcast " + r);
15430            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15431            if (!replaced) {
15432                queue.enqueueParallelBroadcastLocked(r);
15433                queue.scheduleBroadcastsLocked();
15434            }
15435            registeredReceivers = null;
15436            NR = 0;
15437        }
15438
15439        // Merge into one list.
15440        int ir = 0;
15441        if (receivers != null) {
15442            // A special case for PACKAGE_ADDED: do not allow the package
15443            // being added to see this broadcast.  This prevents them from
15444            // using this as a back door to get run as soon as they are
15445            // installed.  Maybe in the future we want to have a special install
15446            // broadcast or such for apps, but we'd like to deliberately make
15447            // this decision.
15448            String skipPackages[] = null;
15449            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15450                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15451                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15452                Uri data = intent.getData();
15453                if (data != null) {
15454                    String pkgName = data.getSchemeSpecificPart();
15455                    if (pkgName != null) {
15456                        skipPackages = new String[] { pkgName };
15457                    }
15458                }
15459            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15460                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15461            }
15462            if (skipPackages != null && (skipPackages.length > 0)) {
15463                for (String skipPackage : skipPackages) {
15464                    if (skipPackage != null) {
15465                        int NT = receivers.size();
15466                        for (int it=0; it<NT; it++) {
15467                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15468                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15469                                receivers.remove(it);
15470                                it--;
15471                                NT--;
15472                            }
15473                        }
15474                    }
15475                }
15476            }
15477
15478            int NT = receivers != null ? receivers.size() : 0;
15479            int it = 0;
15480            ResolveInfo curt = null;
15481            BroadcastFilter curr = null;
15482            while (it < NT && ir < NR) {
15483                if (curt == null) {
15484                    curt = (ResolveInfo)receivers.get(it);
15485                }
15486                if (curr == null) {
15487                    curr = registeredReceivers.get(ir);
15488                }
15489                if (curr.getPriority() >= curt.priority) {
15490                    // Insert this broadcast record into the final list.
15491                    receivers.add(it, curr);
15492                    ir++;
15493                    curr = null;
15494                    it++;
15495                    NT++;
15496                } else {
15497                    // Skip to the next ResolveInfo in the final list.
15498                    it++;
15499                    curt = null;
15500                }
15501            }
15502        }
15503        while (ir < NR) {
15504            if (receivers == null) {
15505                receivers = new ArrayList();
15506            }
15507            receivers.add(registeredReceivers.get(ir));
15508            ir++;
15509        }
15510
15511        if ((receivers != null && receivers.size() > 0)
15512                || resultTo != null) {
15513            BroadcastQueue queue = broadcastQueueForIntent(intent);
15514            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15515                    callerPackage, callingPid, callingUid, resolvedType,
15516                    requiredPermission, appOp, receivers, resultTo, resultCode,
15517                    resultData, map, ordered, sticky, false, userId);
15518            if (DEBUG_BROADCAST) Slog.v(
15519                    TAG, "Enqueueing ordered broadcast " + r
15520                    + ": prev had " + queue.mOrderedBroadcasts.size());
15521            if (DEBUG_BROADCAST) {
15522                int seq = r.intent.getIntExtra("seq", -1);
15523                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15524            }
15525            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15526            if (!replaced) {
15527                queue.enqueueOrderedBroadcastLocked(r);
15528                queue.scheduleBroadcastsLocked();
15529            }
15530        }
15531
15532        return ActivityManager.BROADCAST_SUCCESS;
15533    }
15534
15535    final Intent verifyBroadcastLocked(Intent intent) {
15536        // Refuse possible leaked file descriptors
15537        if (intent != null && intent.hasFileDescriptors() == true) {
15538            throw new IllegalArgumentException("File descriptors passed in Intent");
15539        }
15540
15541        int flags = intent.getFlags();
15542
15543        if (!mProcessesReady) {
15544            // if the caller really truly claims to know what they're doing, go
15545            // ahead and allow the broadcast without launching any receivers
15546            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15547                intent = new Intent(intent);
15548                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15549            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15550                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15551                        + " before boot completion");
15552                throw new IllegalStateException("Cannot broadcast before boot completed");
15553            }
15554        }
15555
15556        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15557            throw new IllegalArgumentException(
15558                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15559        }
15560
15561        return intent;
15562    }
15563
15564    public final int broadcastIntent(IApplicationThread caller,
15565            Intent intent, String resolvedType, IIntentReceiver resultTo,
15566            int resultCode, String resultData, Bundle map,
15567            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15568        enforceNotIsolatedCaller("broadcastIntent");
15569        synchronized(this) {
15570            intent = verifyBroadcastLocked(intent);
15571
15572            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15573            final int callingPid = Binder.getCallingPid();
15574            final int callingUid = Binder.getCallingUid();
15575            final long origId = Binder.clearCallingIdentity();
15576            int res = broadcastIntentLocked(callerApp,
15577                    callerApp != null ? callerApp.info.packageName : null,
15578                    intent, resolvedType, resultTo,
15579                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15580                    callingPid, callingUid, userId);
15581            Binder.restoreCallingIdentity(origId);
15582            return res;
15583        }
15584    }
15585
15586    int broadcastIntentInPackage(String packageName, int uid,
15587            Intent intent, String resolvedType, IIntentReceiver resultTo,
15588            int resultCode, String resultData, Bundle map,
15589            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15590        synchronized(this) {
15591            intent = verifyBroadcastLocked(intent);
15592
15593            final long origId = Binder.clearCallingIdentity();
15594            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15595                    resultTo, resultCode, resultData, map, requiredPermission,
15596                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15597            Binder.restoreCallingIdentity(origId);
15598            return res;
15599        }
15600    }
15601
15602    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15603        // Refuse possible leaked file descriptors
15604        if (intent != null && intent.hasFileDescriptors() == true) {
15605            throw new IllegalArgumentException("File descriptors passed in Intent");
15606        }
15607
15608        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15609                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15610
15611        synchronized(this) {
15612            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15613                    != PackageManager.PERMISSION_GRANTED) {
15614                String msg = "Permission Denial: unbroadcastIntent() from pid="
15615                        + Binder.getCallingPid()
15616                        + ", uid=" + Binder.getCallingUid()
15617                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15618                Slog.w(TAG, msg);
15619                throw new SecurityException(msg);
15620            }
15621            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15622            if (stickies != null) {
15623                ArrayList<Intent> list = stickies.get(intent.getAction());
15624                if (list != null) {
15625                    int N = list.size();
15626                    int i;
15627                    for (i=0; i<N; i++) {
15628                        if (intent.filterEquals(list.get(i))) {
15629                            list.remove(i);
15630                            break;
15631                        }
15632                    }
15633                    if (list.size() <= 0) {
15634                        stickies.remove(intent.getAction());
15635                    }
15636                }
15637                if (stickies.size() <= 0) {
15638                    mStickyBroadcasts.remove(userId);
15639                }
15640            }
15641        }
15642    }
15643
15644    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15645            String resultData, Bundle resultExtras, boolean resultAbort) {
15646        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15647        if (r == null) {
15648            Slog.w(TAG, "finishReceiver called but not found on queue");
15649            return false;
15650        }
15651
15652        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15653    }
15654
15655    void backgroundServicesFinishedLocked(int userId) {
15656        for (BroadcastQueue queue : mBroadcastQueues) {
15657            queue.backgroundServicesFinishedLocked(userId);
15658        }
15659    }
15660
15661    public void finishReceiver(IBinder who, int resultCode, String resultData,
15662            Bundle resultExtras, boolean resultAbort) {
15663        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15664
15665        // Refuse possible leaked file descriptors
15666        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15667            throw new IllegalArgumentException("File descriptors passed in Bundle");
15668        }
15669
15670        final long origId = Binder.clearCallingIdentity();
15671        try {
15672            boolean doNext = false;
15673            BroadcastRecord r;
15674
15675            synchronized(this) {
15676                r = broadcastRecordForReceiverLocked(who);
15677                if (r != null) {
15678                    doNext = r.queue.finishReceiverLocked(r, resultCode,
15679                        resultData, resultExtras, resultAbort, true);
15680                }
15681            }
15682
15683            if (doNext) {
15684                r.queue.processNextBroadcast(false);
15685            }
15686            trimApplications();
15687        } finally {
15688            Binder.restoreCallingIdentity(origId);
15689        }
15690    }
15691
15692    // =========================================================
15693    // INSTRUMENTATION
15694    // =========================================================
15695
15696    public boolean startInstrumentation(ComponentName className,
15697            String profileFile, int flags, Bundle arguments,
15698            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
15699            int userId, String abiOverride) {
15700        enforceNotIsolatedCaller("startInstrumentation");
15701        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15702                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
15703        // Refuse possible leaked file descriptors
15704        if (arguments != null && arguments.hasFileDescriptors()) {
15705            throw new IllegalArgumentException("File descriptors passed in Bundle");
15706        }
15707
15708        synchronized(this) {
15709            InstrumentationInfo ii = null;
15710            ApplicationInfo ai = null;
15711            try {
15712                ii = mContext.getPackageManager().getInstrumentationInfo(
15713                    className, STOCK_PM_FLAGS);
15714                ai = AppGlobals.getPackageManager().getApplicationInfo(
15715                        ii.targetPackage, STOCK_PM_FLAGS, userId);
15716            } catch (PackageManager.NameNotFoundException e) {
15717            } catch (RemoteException e) {
15718            }
15719            if (ii == null) {
15720                reportStartInstrumentationFailure(watcher, className,
15721                        "Unable to find instrumentation info for: " + className);
15722                return false;
15723            }
15724            if (ai == null) {
15725                reportStartInstrumentationFailure(watcher, className,
15726                        "Unable to find instrumentation target package: " + ii.targetPackage);
15727                return false;
15728            }
15729
15730            int match = mContext.getPackageManager().checkSignatures(
15731                    ii.targetPackage, ii.packageName);
15732            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15733                String msg = "Permission Denial: starting instrumentation "
15734                        + className + " from pid="
15735                        + Binder.getCallingPid()
15736                        + ", uid=" + Binder.getCallingPid()
15737                        + " not allowed because package " + ii.packageName
15738                        + " does not have a signature matching the target "
15739                        + ii.targetPackage;
15740                reportStartInstrumentationFailure(watcher, className, msg);
15741                throw new SecurityException(msg);
15742            }
15743
15744            final long origId = Binder.clearCallingIdentity();
15745            // Instrumentation can kill and relaunch even persistent processes
15746            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15747                    "start instr");
15748            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15749            app.instrumentationClass = className;
15750            app.instrumentationInfo = ai;
15751            app.instrumentationProfileFile = profileFile;
15752            app.instrumentationArguments = arguments;
15753            app.instrumentationWatcher = watcher;
15754            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15755            app.instrumentationResultClass = className;
15756            Binder.restoreCallingIdentity(origId);
15757        }
15758
15759        return true;
15760    }
15761
15762    /**
15763     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15764     * error to the logs, but if somebody is watching, send the report there too.  This enables
15765     * the "am" command to report errors with more information.
15766     *
15767     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15768     * @param cn The component name of the instrumentation.
15769     * @param report The error report.
15770     */
15771    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
15772            ComponentName cn, String report) {
15773        Slog.w(TAG, report);
15774        try {
15775            if (watcher != null) {
15776                Bundle results = new Bundle();
15777                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
15778                results.putString("Error", report);
15779                watcher.instrumentationStatus(cn, -1, results);
15780            }
15781        } catch (RemoteException e) {
15782            Slog.w(TAG, e);
15783        }
15784    }
15785
15786    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
15787        if (app.instrumentationWatcher != null) {
15788            try {
15789                // NOTE:  IInstrumentationWatcher *must* be oneway here
15790                app.instrumentationWatcher.instrumentationFinished(
15791                    app.instrumentationClass,
15792                    resultCode,
15793                    results);
15794            } catch (RemoteException e) {
15795            }
15796        }
15797        if (app.instrumentationUiAutomationConnection != null) {
15798            try {
15799                app.instrumentationUiAutomationConnection.shutdown();
15800            } catch (RemoteException re) {
15801                /* ignore */
15802            }
15803            // Only a UiAutomation can set this flag and now that
15804            // it is finished we make sure it is reset to its default.
15805            mUserIsMonkey = false;
15806        }
15807        app.instrumentationWatcher = null;
15808        app.instrumentationUiAutomationConnection = null;
15809        app.instrumentationClass = null;
15810        app.instrumentationInfo = null;
15811        app.instrumentationProfileFile = null;
15812        app.instrumentationArguments = null;
15813
15814        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
15815                "finished inst");
15816    }
15817
15818    public void finishInstrumentation(IApplicationThread target,
15819            int resultCode, Bundle results) {
15820        int userId = UserHandle.getCallingUserId();
15821        // Refuse possible leaked file descriptors
15822        if (results != null && results.hasFileDescriptors()) {
15823            throw new IllegalArgumentException("File descriptors passed in Intent");
15824        }
15825
15826        synchronized(this) {
15827            ProcessRecord app = getRecordForAppLocked(target);
15828            if (app == null) {
15829                Slog.w(TAG, "finishInstrumentation: no app for " + target);
15830                return;
15831            }
15832            final long origId = Binder.clearCallingIdentity();
15833            finishInstrumentationLocked(app, resultCode, results);
15834            Binder.restoreCallingIdentity(origId);
15835        }
15836    }
15837
15838    // =========================================================
15839    // CONFIGURATION
15840    // =========================================================
15841
15842    public ConfigurationInfo getDeviceConfigurationInfo() {
15843        ConfigurationInfo config = new ConfigurationInfo();
15844        synchronized (this) {
15845            config.reqTouchScreen = mConfiguration.touchscreen;
15846            config.reqKeyboardType = mConfiguration.keyboard;
15847            config.reqNavigation = mConfiguration.navigation;
15848            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
15849                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
15850                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
15851            }
15852            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
15853                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
15854                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
15855            }
15856            config.reqGlEsVersion = GL_ES_VERSION;
15857        }
15858        return config;
15859    }
15860
15861    ActivityStack getFocusedStack() {
15862        return mStackSupervisor.getFocusedStack();
15863    }
15864
15865    public Configuration getConfiguration() {
15866        Configuration ci;
15867        synchronized(this) {
15868            ci = new Configuration(mConfiguration);
15869        }
15870        return ci;
15871    }
15872
15873    public void updatePersistentConfiguration(Configuration values) {
15874        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15875                "updateConfiguration()");
15876        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
15877                "updateConfiguration()");
15878        if (values == null) {
15879            throw new NullPointerException("Configuration must not be null");
15880        }
15881
15882        synchronized(this) {
15883            final long origId = Binder.clearCallingIdentity();
15884            updateConfigurationLocked(values, null, true, false);
15885            Binder.restoreCallingIdentity(origId);
15886        }
15887    }
15888
15889    public void updateConfiguration(Configuration values) {
15890        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15891                "updateConfiguration()");
15892
15893        synchronized(this) {
15894            if (values == null && mWindowManager != null) {
15895                // sentinel: fetch the current configuration from the window manager
15896                values = mWindowManager.computeNewConfiguration();
15897            }
15898
15899            if (mWindowManager != null) {
15900                mProcessList.applyDisplaySize(mWindowManager);
15901            }
15902
15903            final long origId = Binder.clearCallingIdentity();
15904            if (values != null) {
15905                Settings.System.clearConfiguration(values);
15906            }
15907            updateConfigurationLocked(values, null, false, false);
15908            Binder.restoreCallingIdentity(origId);
15909        }
15910    }
15911
15912    /**
15913     * Do either or both things: (1) change the current configuration, and (2)
15914     * make sure the given activity is running with the (now) current
15915     * configuration.  Returns true if the activity has been left running, or
15916     * false if <var>starting</var> is being destroyed to match the new
15917     * configuration.
15918     * @param persistent TODO
15919     */
15920    boolean updateConfigurationLocked(Configuration values,
15921            ActivityRecord starting, boolean persistent, boolean initLocale) {
15922        int changes = 0;
15923
15924        if (values != null) {
15925            Configuration newConfig = new Configuration(mConfiguration);
15926            changes = newConfig.updateFrom(values);
15927            if (changes != 0) {
15928                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
15929                    Slog.i(TAG, "Updating configuration to: " + values);
15930                }
15931
15932                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15933
15934                if (values.locale != null && !initLocale) {
15935                    saveLocaleLocked(values.locale,
15936                                     !values.locale.equals(mConfiguration.locale),
15937                                     values.userSetLocale);
15938                }
15939
15940                mConfigurationSeq++;
15941                if (mConfigurationSeq <= 0) {
15942                    mConfigurationSeq = 1;
15943                }
15944                newConfig.seq = mConfigurationSeq;
15945                mConfiguration = newConfig;
15946                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15947                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
15948                //mUsageStatsService.noteStartConfig(newConfig);
15949
15950                final Configuration configCopy = new Configuration(mConfiguration);
15951
15952                // TODO: If our config changes, should we auto dismiss any currently
15953                // showing dialogs?
15954                mShowDialogs = shouldShowDialogs(newConfig);
15955
15956                AttributeCache ac = AttributeCache.instance();
15957                if (ac != null) {
15958                    ac.updateConfiguration(configCopy);
15959                }
15960
15961                // Make sure all resources in our process are updated
15962                // right now, so that anyone who is going to retrieve
15963                // resource values after we return will be sure to get
15964                // the new ones.  This is especially important during
15965                // boot, where the first config change needs to guarantee
15966                // all resources have that config before following boot
15967                // code is executed.
15968                mSystemThread.applyConfigurationToResources(configCopy);
15969
15970                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15971                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15972                    msg.obj = new Configuration(configCopy);
15973                    mHandler.sendMessage(msg);
15974                }
15975
15976                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15977                    ProcessRecord app = mLruProcesses.get(i);
15978                    try {
15979                        if (app.thread != null) {
15980                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15981                                    + app.processName + " new config " + mConfiguration);
15982                            app.thread.scheduleConfigurationChanged(configCopy);
15983                        }
15984                    } catch (Exception e) {
15985                    }
15986                }
15987                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15988                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15989                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15990                        | Intent.FLAG_RECEIVER_FOREGROUND);
15991                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15992                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15993                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15994                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
15995                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
15996                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15997                    broadcastIntentLocked(null, null, intent,
15998                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15999                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16000                }
16001            }
16002        }
16003
16004        boolean kept = true;
16005        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16006        // mainStack is null during startup.
16007        if (mainStack != null) {
16008            if (changes != 0 && starting == null) {
16009                // If the configuration changed, and the caller is not already
16010                // in the process of starting an activity, then find the top
16011                // activity to check if its configuration needs to change.
16012                starting = mainStack.topRunningActivityLocked(null);
16013            }
16014
16015            if (starting != null) {
16016                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16017                // And we need to make sure at this point that all other activities
16018                // are made visible with the correct configuration.
16019                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16020            }
16021        }
16022
16023        if (values != null && mWindowManager != null) {
16024            mWindowManager.setNewConfiguration(mConfiguration);
16025        }
16026
16027        return kept;
16028    }
16029
16030    /**
16031     * Decide based on the configuration whether we should shouw the ANR,
16032     * crash, etc dialogs.  The idea is that if there is no affordnace to
16033     * press the on-screen buttons, we shouldn't show the dialog.
16034     *
16035     * A thought: SystemUI might also want to get told about this, the Power
16036     * dialog / global actions also might want different behaviors.
16037     */
16038    private static final boolean shouldShowDialogs(Configuration config) {
16039        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16040                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16041    }
16042
16043    /**
16044     * Save the locale.  You must be inside a synchronized (this) block.
16045     */
16046    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16047        if(isDiff) {
16048            SystemProperties.set("user.language", l.getLanguage());
16049            SystemProperties.set("user.region", l.getCountry());
16050        }
16051
16052        if(isPersist) {
16053            SystemProperties.set("persist.sys.language", l.getLanguage());
16054            SystemProperties.set("persist.sys.country", l.getCountry());
16055            SystemProperties.set("persist.sys.localevar", l.getVariant());
16056        }
16057    }
16058
16059    @Override
16060    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16061        synchronized (this) {
16062            ActivityRecord srec = ActivityRecord.forToken(token);
16063            if (srec.task != null && srec.task.stack != null) {
16064                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16065            }
16066        }
16067        return false;
16068    }
16069
16070    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16071            Intent resultData) {
16072
16073        synchronized (this) {
16074            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16075            if (stack != null) {
16076                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16077            }
16078            return false;
16079        }
16080    }
16081
16082    public int getLaunchedFromUid(IBinder activityToken) {
16083        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16084        if (srec == null) {
16085            return -1;
16086        }
16087        return srec.launchedFromUid;
16088    }
16089
16090    public String getLaunchedFromPackage(IBinder activityToken) {
16091        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16092        if (srec == null) {
16093            return null;
16094        }
16095        return srec.launchedFromPackage;
16096    }
16097
16098    // =========================================================
16099    // LIFETIME MANAGEMENT
16100    // =========================================================
16101
16102    // Returns which broadcast queue the app is the current [or imminent] receiver
16103    // on, or 'null' if the app is not an active broadcast recipient.
16104    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16105        BroadcastRecord r = app.curReceiver;
16106        if (r != null) {
16107            return r.queue;
16108        }
16109
16110        // It's not the current receiver, but it might be starting up to become one
16111        synchronized (this) {
16112            for (BroadcastQueue queue : mBroadcastQueues) {
16113                r = queue.mPendingBroadcast;
16114                if (r != null && r.curApp == app) {
16115                    // found it; report which queue it's in
16116                    return queue;
16117                }
16118            }
16119        }
16120
16121        return null;
16122    }
16123
16124    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16125            boolean doingAll, long now) {
16126        if (mAdjSeq == app.adjSeq) {
16127            // This adjustment has already been computed.
16128            return app.curRawAdj;
16129        }
16130
16131        if (app.thread == null) {
16132            app.adjSeq = mAdjSeq;
16133            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16134            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16135            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16136        }
16137
16138        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16139        app.adjSource = null;
16140        app.adjTarget = null;
16141        app.empty = false;
16142        app.cached = false;
16143
16144        final int activitiesSize = app.activities.size();
16145
16146        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16147            // The max adjustment doesn't allow this app to be anything
16148            // below foreground, so it is not worth doing work for it.
16149            app.adjType = "fixed";
16150            app.adjSeq = mAdjSeq;
16151            app.curRawAdj = app.maxAdj;
16152            app.foregroundActivities = false;
16153            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16154            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16155            // System processes can do UI, and when they do we want to have
16156            // them trim their memory after the user leaves the UI.  To
16157            // facilitate this, here we need to determine whether or not it
16158            // is currently showing UI.
16159            app.systemNoUi = true;
16160            if (app == TOP_APP) {
16161                app.systemNoUi = false;
16162            } else if (activitiesSize > 0) {
16163                for (int j = 0; j < activitiesSize; j++) {
16164                    final ActivityRecord r = app.activities.get(j);
16165                    if (r.visible) {
16166                        app.systemNoUi = false;
16167                    }
16168                }
16169            }
16170            if (!app.systemNoUi) {
16171                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16172            }
16173            return (app.curAdj=app.maxAdj);
16174        }
16175
16176        app.systemNoUi = false;
16177
16178        // Determine the importance of the process, starting with most
16179        // important to least, and assign an appropriate OOM adjustment.
16180        int adj;
16181        int schedGroup;
16182        int procState;
16183        boolean foregroundActivities = false;
16184        BroadcastQueue queue;
16185        if (app == TOP_APP) {
16186            // The last app on the list is the foreground app.
16187            adj = ProcessList.FOREGROUND_APP_ADJ;
16188            schedGroup = Process.THREAD_GROUP_DEFAULT;
16189            app.adjType = "top-activity";
16190            foregroundActivities = true;
16191            procState = ActivityManager.PROCESS_STATE_TOP;
16192        } else if (app.instrumentationClass != null) {
16193            // Don't want to kill running instrumentation.
16194            adj = ProcessList.FOREGROUND_APP_ADJ;
16195            schedGroup = Process.THREAD_GROUP_DEFAULT;
16196            app.adjType = "instrumentation";
16197            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16198        } else if ((queue = isReceivingBroadcast(app)) != null) {
16199            // An app that is currently receiving a broadcast also
16200            // counts as being in the foreground for OOM killer purposes.
16201            // It's placed in a sched group based on the nature of the
16202            // broadcast as reflected by which queue it's active in.
16203            adj = ProcessList.FOREGROUND_APP_ADJ;
16204            schedGroup = (queue == mFgBroadcastQueue)
16205                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16206            app.adjType = "broadcast";
16207            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16208        } else if (app.executingServices.size() > 0) {
16209            // An app that is currently executing a service callback also
16210            // counts as being in the foreground.
16211            adj = ProcessList.FOREGROUND_APP_ADJ;
16212            schedGroup = app.execServicesFg ?
16213                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16214            app.adjType = "exec-service";
16215            procState = ActivityManager.PROCESS_STATE_SERVICE;
16216            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16217        } else {
16218            // As far as we know the process is empty.  We may change our mind later.
16219            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16220            // At this point we don't actually know the adjustment.  Use the cached adj
16221            // value that the caller wants us to.
16222            adj = cachedAdj;
16223            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16224            app.cached = true;
16225            app.empty = true;
16226            app.adjType = "cch-empty";
16227        }
16228
16229        // Examine all activities if not already foreground.
16230        if (!foregroundActivities && activitiesSize > 0) {
16231            for (int j = 0; j < activitiesSize; j++) {
16232                final ActivityRecord r = app.activities.get(j);
16233                if (r.app != app) {
16234                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16235                            + app + "?!?");
16236                    continue;
16237                }
16238                if (r.visible) {
16239                    // App has a visible activity; only upgrade adjustment.
16240                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16241                        adj = ProcessList.VISIBLE_APP_ADJ;
16242                        app.adjType = "visible";
16243                    }
16244                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16245                        procState = ActivityManager.PROCESS_STATE_TOP;
16246                    }
16247                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16248                    app.cached = false;
16249                    app.empty = false;
16250                    foregroundActivities = true;
16251                    break;
16252                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16253                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16254                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16255                        app.adjType = "pausing";
16256                    }
16257                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16258                        procState = ActivityManager.PROCESS_STATE_TOP;
16259                    }
16260                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16261                    app.cached = false;
16262                    app.empty = false;
16263                    foregroundActivities = true;
16264                } else if (r.state == ActivityState.STOPPING) {
16265                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16266                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16267                        app.adjType = "stopping";
16268                    }
16269                    // For the process state, we will at this point consider the
16270                    // process to be cached.  It will be cached either as an activity
16271                    // or empty depending on whether the activity is finishing.  We do
16272                    // this so that we can treat the process as cached for purposes of
16273                    // memory trimming (determing current memory level, trim command to
16274                    // send to process) since there can be an arbitrary number of stopping
16275                    // processes and they should soon all go into the cached state.
16276                    if (!r.finishing) {
16277                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16278                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16279                        }
16280                    }
16281                    app.cached = false;
16282                    app.empty = false;
16283                    foregroundActivities = true;
16284                } else {
16285                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16286                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16287                        app.adjType = "cch-act";
16288                    }
16289                }
16290            }
16291        }
16292
16293        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16294            if (app.foregroundServices) {
16295                // The user is aware of this app, so make it visible.
16296                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16297                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16298                app.cached = false;
16299                app.adjType = "fg-service";
16300                schedGroup = Process.THREAD_GROUP_DEFAULT;
16301            } else if (app.forcingToForeground != null) {
16302                // The user is aware of this app, so make it visible.
16303                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16304                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16305                app.cached = false;
16306                app.adjType = "force-fg";
16307                app.adjSource = app.forcingToForeground;
16308                schedGroup = Process.THREAD_GROUP_DEFAULT;
16309            }
16310        }
16311
16312        if (app == mHeavyWeightProcess) {
16313            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16314                // We don't want to kill the current heavy-weight process.
16315                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16316                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16317                app.cached = false;
16318                app.adjType = "heavy";
16319            }
16320            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16321                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16322            }
16323        }
16324
16325        if (app == mHomeProcess) {
16326            if (adj > ProcessList.HOME_APP_ADJ) {
16327                // This process is hosting what we currently consider to be the
16328                // home app, so we don't want to let it go into the background.
16329                adj = ProcessList.HOME_APP_ADJ;
16330                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16331                app.cached = false;
16332                app.adjType = "home";
16333            }
16334            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16335                procState = ActivityManager.PROCESS_STATE_HOME;
16336            }
16337        }
16338
16339        if (app == mPreviousProcess && app.activities.size() > 0) {
16340            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16341                // This was the previous process that showed UI to the user.
16342                // We want to try to keep it around more aggressively, to give
16343                // a good experience around switching between two apps.
16344                adj = ProcessList.PREVIOUS_APP_ADJ;
16345                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16346                app.cached = false;
16347                app.adjType = "previous";
16348            }
16349            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16350                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16351            }
16352        }
16353
16354        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16355                + " reason=" + app.adjType);
16356
16357        // By default, we use the computed adjustment.  It may be changed if
16358        // there are applications dependent on our services or providers, but
16359        // this gives us a baseline and makes sure we don't get into an
16360        // infinite recursion.
16361        app.adjSeq = mAdjSeq;
16362        app.curRawAdj = adj;
16363        app.hasStartedServices = false;
16364
16365        if (mBackupTarget != null && app == mBackupTarget.app) {
16366            // If possible we want to avoid killing apps while they're being backed up
16367            if (adj > ProcessList.BACKUP_APP_ADJ) {
16368                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16369                adj = ProcessList.BACKUP_APP_ADJ;
16370                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16371                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16372                }
16373                app.adjType = "backup";
16374                app.cached = false;
16375            }
16376            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16377                procState = ActivityManager.PROCESS_STATE_BACKUP;
16378            }
16379        }
16380
16381        boolean mayBeTop = false;
16382
16383        for (int is = app.services.size()-1;
16384                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16385                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16386                        || procState > ActivityManager.PROCESS_STATE_TOP);
16387                is--) {
16388            ServiceRecord s = app.services.valueAt(is);
16389            if (s.startRequested) {
16390                app.hasStartedServices = true;
16391                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16392                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16393                }
16394                if (app.hasShownUi && app != mHomeProcess) {
16395                    // If this process has shown some UI, let it immediately
16396                    // go to the LRU list because it may be pretty heavy with
16397                    // UI stuff.  We'll tag it with a label just to help
16398                    // debug and understand what is going on.
16399                    if (adj > ProcessList.SERVICE_ADJ) {
16400                        app.adjType = "cch-started-ui-services";
16401                    }
16402                } else {
16403                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16404                        // This service has seen some activity within
16405                        // recent memory, so we will keep its process ahead
16406                        // of the background processes.
16407                        if (adj > ProcessList.SERVICE_ADJ) {
16408                            adj = ProcessList.SERVICE_ADJ;
16409                            app.adjType = "started-services";
16410                            app.cached = false;
16411                        }
16412                    }
16413                    // If we have let the service slide into the background
16414                    // state, still have some text describing what it is doing
16415                    // even though the service no longer has an impact.
16416                    if (adj > ProcessList.SERVICE_ADJ) {
16417                        app.adjType = "cch-started-services";
16418                    }
16419                }
16420            }
16421            for (int conni = s.connections.size()-1;
16422                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16423                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16424                            || procState > ActivityManager.PROCESS_STATE_TOP);
16425                    conni--) {
16426                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16427                for (int i = 0;
16428                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16429                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16430                                || procState > ActivityManager.PROCESS_STATE_TOP);
16431                        i++) {
16432                    // XXX should compute this based on the max of
16433                    // all connected clients.
16434                    ConnectionRecord cr = clist.get(i);
16435                    if (cr.binding.client == app) {
16436                        // Binding to ourself is not interesting.
16437                        continue;
16438                    }
16439                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16440                        ProcessRecord client = cr.binding.client;
16441                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16442                                TOP_APP, doingAll, now);
16443                        int clientProcState = client.curProcState;
16444                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16445                            // If the other app is cached for any reason, for purposes here
16446                            // we are going to consider it empty.  The specific cached state
16447                            // doesn't propagate except under certain conditions.
16448                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16449                        }
16450                        String adjType = null;
16451                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16452                            // Not doing bind OOM management, so treat
16453                            // this guy more like a started service.
16454                            if (app.hasShownUi && app != mHomeProcess) {
16455                                // If this process has shown some UI, let it immediately
16456                                // go to the LRU list because it may be pretty heavy with
16457                                // UI stuff.  We'll tag it with a label just to help
16458                                // debug and understand what is going on.
16459                                if (adj > clientAdj) {
16460                                    adjType = "cch-bound-ui-services";
16461                                }
16462                                app.cached = false;
16463                                clientAdj = adj;
16464                                clientProcState = procState;
16465                            } else {
16466                                if (now >= (s.lastActivity
16467                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16468                                    // This service has not seen activity within
16469                                    // recent memory, so allow it to drop to the
16470                                    // LRU list if there is no other reason to keep
16471                                    // it around.  We'll also tag it with a label just
16472                                    // to help debug and undertand what is going on.
16473                                    if (adj > clientAdj) {
16474                                        adjType = "cch-bound-services";
16475                                    }
16476                                    clientAdj = adj;
16477                                }
16478                            }
16479                        }
16480                        if (adj > clientAdj) {
16481                            // If this process has recently shown UI, and
16482                            // the process that is binding to it is less
16483                            // important than being visible, then we don't
16484                            // care about the binding as much as we care
16485                            // about letting this process get into the LRU
16486                            // list to be killed and restarted if needed for
16487                            // memory.
16488                            if (app.hasShownUi && app != mHomeProcess
16489                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16490                                adjType = "cch-bound-ui-services";
16491                            } else {
16492                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16493                                        |Context.BIND_IMPORTANT)) != 0) {
16494                                    adj = clientAdj;
16495                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16496                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16497                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16498                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16499                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16500                                    adj = clientAdj;
16501                                } else {
16502                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16503                                        adj = ProcessList.VISIBLE_APP_ADJ;
16504                                    }
16505                                }
16506                                if (!client.cached) {
16507                                    app.cached = false;
16508                                }
16509                                adjType = "service";
16510                            }
16511                        }
16512                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16513                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16514                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16515                            }
16516                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16517                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16518                                    // Special handling of clients who are in the top state.
16519                                    // We *may* want to consider this process to be in the
16520                                    // top state as well, but only if there is not another
16521                                    // reason for it to be running.  Being on the top is a
16522                                    // special state, meaning you are specifically running
16523                                    // for the current top app.  If the process is already
16524                                    // running in the background for some other reason, it
16525                                    // is more important to continue considering it to be
16526                                    // in the background state.
16527                                    mayBeTop = true;
16528                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16529                                } else {
16530                                    // Special handling for above-top states (persistent
16531                                    // processes).  These should not bring the current process
16532                                    // into the top state, since they are not on top.  Instead
16533                                    // give them the best state after that.
16534                                    clientProcState =
16535                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16536                                }
16537                            }
16538                        } else {
16539                            if (clientProcState <
16540                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16541                                clientProcState =
16542                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16543                            }
16544                        }
16545                        if (procState > clientProcState) {
16546                            procState = clientProcState;
16547                        }
16548                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16549                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16550                            app.pendingUiClean = true;
16551                        }
16552                        if (adjType != null) {
16553                            app.adjType = adjType;
16554                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16555                                    .REASON_SERVICE_IN_USE;
16556                            app.adjSource = cr.binding.client;
16557                            app.adjSourceProcState = clientProcState;
16558                            app.adjTarget = s.name;
16559                        }
16560                    }
16561                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16562                        app.treatLikeActivity = true;
16563                    }
16564                    final ActivityRecord a = cr.activity;
16565                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16566                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16567                                (a.visible || a.state == ActivityState.RESUMED
16568                                 || a.state == ActivityState.PAUSING)) {
16569                            adj = ProcessList.FOREGROUND_APP_ADJ;
16570                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16571                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16572                            }
16573                            app.cached = false;
16574                            app.adjType = "service";
16575                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16576                                    .REASON_SERVICE_IN_USE;
16577                            app.adjSource = a;
16578                            app.adjSourceProcState = procState;
16579                            app.adjTarget = s.name;
16580                        }
16581                    }
16582                }
16583            }
16584        }
16585
16586        for (int provi = app.pubProviders.size()-1;
16587                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16588                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16589                        || procState > ActivityManager.PROCESS_STATE_TOP);
16590                provi--) {
16591            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16592            for (int i = cpr.connections.size()-1;
16593                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16594                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16595                            || procState > ActivityManager.PROCESS_STATE_TOP);
16596                    i--) {
16597                ContentProviderConnection conn = cpr.connections.get(i);
16598                ProcessRecord client = conn.client;
16599                if (client == app) {
16600                    // Being our own client is not interesting.
16601                    continue;
16602                }
16603                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16604                int clientProcState = client.curProcState;
16605                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16606                    // If the other app is cached for any reason, for purposes here
16607                    // we are going to consider it empty.
16608                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16609                }
16610                if (adj > clientAdj) {
16611                    if (app.hasShownUi && app != mHomeProcess
16612                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16613                        app.adjType = "cch-ui-provider";
16614                    } else {
16615                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16616                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16617                        app.adjType = "provider";
16618                    }
16619                    app.cached &= client.cached;
16620                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16621                            .REASON_PROVIDER_IN_USE;
16622                    app.adjSource = client;
16623                    app.adjSourceProcState = clientProcState;
16624                    app.adjTarget = cpr.name;
16625                }
16626                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16627                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16628                        // Special handling of clients who are in the top state.
16629                        // We *may* want to consider this process to be in the
16630                        // top state as well, but only if there is not another
16631                        // reason for it to be running.  Being on the top is a
16632                        // special state, meaning you are specifically running
16633                        // for the current top app.  If the process is already
16634                        // running in the background for some other reason, it
16635                        // is more important to continue considering it to be
16636                        // in the background state.
16637                        mayBeTop = true;
16638                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16639                    } else {
16640                        // Special handling for above-top states (persistent
16641                        // processes).  These should not bring the current process
16642                        // into the top state, since they are not on top.  Instead
16643                        // give them the best state after that.
16644                        clientProcState =
16645                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16646                    }
16647                }
16648                if (procState > clientProcState) {
16649                    procState = clientProcState;
16650                }
16651                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16652                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16653                }
16654            }
16655            // If the provider has external (non-framework) process
16656            // dependencies, ensure that its adjustment is at least
16657            // FOREGROUND_APP_ADJ.
16658            if (cpr.hasExternalProcessHandles()) {
16659                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16660                    adj = ProcessList.FOREGROUND_APP_ADJ;
16661                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16662                    app.cached = false;
16663                    app.adjType = "provider";
16664                    app.adjTarget = cpr.name;
16665                }
16666                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16667                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16668                }
16669            }
16670        }
16671
16672        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16673            // A client of one of our services or providers is in the top state.  We
16674            // *may* want to be in the top state, but not if we are already running in
16675            // the background for some other reason.  For the decision here, we are going
16676            // to pick out a few specific states that we want to remain in when a client
16677            // is top (states that tend to be longer-term) and otherwise allow it to go
16678            // to the top state.
16679            switch (procState) {
16680                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
16681                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
16682                case ActivityManager.PROCESS_STATE_SERVICE:
16683                    // These all are longer-term states, so pull them up to the top
16684                    // of the background states, but not all the way to the top state.
16685                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16686                    break;
16687                default:
16688                    // Otherwise, top is a better choice, so take it.
16689                    procState = ActivityManager.PROCESS_STATE_TOP;
16690                    break;
16691            }
16692        }
16693
16694        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
16695            if (app.hasClientActivities) {
16696                // This is a cached process, but with client activities.  Mark it so.
16697                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
16698                app.adjType = "cch-client-act";
16699            } else if (app.treatLikeActivity) {
16700                // This is a cached process, but somebody wants us to treat it like it has
16701                // an activity, okay!
16702                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16703                app.adjType = "cch-as-act";
16704            }
16705        }
16706
16707        if (adj == ProcessList.SERVICE_ADJ) {
16708            if (doingAll) {
16709                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
16710                mNewNumServiceProcs++;
16711                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
16712                if (!app.serviceb) {
16713                    // This service isn't far enough down on the LRU list to
16714                    // normally be a B service, but if we are low on RAM and it
16715                    // is large we want to force it down since we would prefer to
16716                    // keep launcher over it.
16717                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
16718                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
16719                        app.serviceHighRam = true;
16720                        app.serviceb = true;
16721                        //Slog.i(TAG, "ADJ " + app + " high ram!");
16722                    } else {
16723                        mNewNumAServiceProcs++;
16724                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
16725                    }
16726                } else {
16727                    app.serviceHighRam = false;
16728                }
16729            }
16730            if (app.serviceb) {
16731                adj = ProcessList.SERVICE_B_ADJ;
16732            }
16733        }
16734
16735        app.curRawAdj = adj;
16736
16737        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16738        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
16739        if (adj > app.maxAdj) {
16740            adj = app.maxAdj;
16741            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
16742                schedGroup = Process.THREAD_GROUP_DEFAULT;
16743            }
16744        }
16745
16746        // Do final modification to adj.  Everything we do between here and applying
16747        // the final setAdj must be done in this function, because we will also use
16748        // it when computing the final cached adj later.  Note that we don't need to
16749        // worry about this for max adj above, since max adj will always be used to
16750        // keep it out of the cached vaues.
16751        app.curAdj = app.modifyRawOomAdj(adj);
16752        app.curSchedGroup = schedGroup;
16753        app.curProcState = procState;
16754        app.foregroundActivities = foregroundActivities;
16755
16756        return app.curRawAdj;
16757    }
16758
16759    /**
16760     * Schedule PSS collection of a process.
16761     */
16762    void requestPssLocked(ProcessRecord proc, int procState) {
16763        if (mPendingPssProcesses.contains(proc)) {
16764            return;
16765        }
16766        if (mPendingPssProcesses.size() == 0) {
16767            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16768        }
16769        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
16770        proc.pssProcState = procState;
16771        mPendingPssProcesses.add(proc);
16772    }
16773
16774    /**
16775     * Schedule PSS collection of all processes.
16776     */
16777    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
16778        if (!always) {
16779            if (now < (mLastFullPssTime +
16780                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
16781                return;
16782            }
16783        }
16784        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
16785        mLastFullPssTime = now;
16786        mFullPssPending = true;
16787        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
16788        mPendingPssProcesses.clear();
16789        for (int i=mLruProcesses.size()-1; i>=0; i--) {
16790            ProcessRecord app = mLruProcesses.get(i);
16791            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
16792                app.pssProcState = app.setProcState;
16793                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16794                        isSleeping(), now);
16795                mPendingPssProcesses.add(app);
16796            }
16797        }
16798        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16799    }
16800
16801    /**
16802     * Ask a given process to GC right now.
16803     */
16804    final void performAppGcLocked(ProcessRecord app) {
16805        try {
16806            app.lastRequestedGc = SystemClock.uptimeMillis();
16807            if (app.thread != null) {
16808                if (app.reportLowMemory) {
16809                    app.reportLowMemory = false;
16810                    app.thread.scheduleLowMemory();
16811                } else {
16812                    app.thread.processInBackground();
16813                }
16814            }
16815        } catch (Exception e) {
16816            // whatever.
16817        }
16818    }
16819
16820    /**
16821     * Returns true if things are idle enough to perform GCs.
16822     */
16823    private final boolean canGcNowLocked() {
16824        boolean processingBroadcasts = false;
16825        for (BroadcastQueue q : mBroadcastQueues) {
16826            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
16827                processingBroadcasts = true;
16828            }
16829        }
16830        return !processingBroadcasts
16831                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
16832    }
16833
16834    /**
16835     * Perform GCs on all processes that are waiting for it, but only
16836     * if things are idle.
16837     */
16838    final void performAppGcsLocked() {
16839        final int N = mProcessesToGc.size();
16840        if (N <= 0) {
16841            return;
16842        }
16843        if (canGcNowLocked()) {
16844            while (mProcessesToGc.size() > 0) {
16845                ProcessRecord proc = mProcessesToGc.remove(0);
16846                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
16847                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
16848                            <= SystemClock.uptimeMillis()) {
16849                        // To avoid spamming the system, we will GC processes one
16850                        // at a time, waiting a few seconds between each.
16851                        performAppGcLocked(proc);
16852                        scheduleAppGcsLocked();
16853                        return;
16854                    } else {
16855                        // It hasn't been long enough since we last GCed this
16856                        // process...  put it in the list to wait for its time.
16857                        addProcessToGcListLocked(proc);
16858                        break;
16859                    }
16860                }
16861            }
16862
16863            scheduleAppGcsLocked();
16864        }
16865    }
16866
16867    /**
16868     * If all looks good, perform GCs on all processes waiting for them.
16869     */
16870    final void performAppGcsIfAppropriateLocked() {
16871        if (canGcNowLocked()) {
16872            performAppGcsLocked();
16873            return;
16874        }
16875        // Still not idle, wait some more.
16876        scheduleAppGcsLocked();
16877    }
16878
16879    /**
16880     * Schedule the execution of all pending app GCs.
16881     */
16882    final void scheduleAppGcsLocked() {
16883        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
16884
16885        if (mProcessesToGc.size() > 0) {
16886            // Schedule a GC for the time to the next process.
16887            ProcessRecord proc = mProcessesToGc.get(0);
16888            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
16889
16890            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
16891            long now = SystemClock.uptimeMillis();
16892            if (when < (now+GC_TIMEOUT)) {
16893                when = now + GC_TIMEOUT;
16894            }
16895            mHandler.sendMessageAtTime(msg, when);
16896        }
16897    }
16898
16899    /**
16900     * Add a process to the array of processes waiting to be GCed.  Keeps the
16901     * list in sorted order by the last GC time.  The process can't already be
16902     * on the list.
16903     */
16904    final void addProcessToGcListLocked(ProcessRecord proc) {
16905        boolean added = false;
16906        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
16907            if (mProcessesToGc.get(i).lastRequestedGc <
16908                    proc.lastRequestedGc) {
16909                added = true;
16910                mProcessesToGc.add(i+1, proc);
16911                break;
16912            }
16913        }
16914        if (!added) {
16915            mProcessesToGc.add(0, proc);
16916        }
16917    }
16918
16919    /**
16920     * Set up to ask a process to GC itself.  This will either do it
16921     * immediately, or put it on the list of processes to gc the next
16922     * time things are idle.
16923     */
16924    final void scheduleAppGcLocked(ProcessRecord app) {
16925        long now = SystemClock.uptimeMillis();
16926        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
16927            return;
16928        }
16929        if (!mProcessesToGc.contains(app)) {
16930            addProcessToGcListLocked(app);
16931            scheduleAppGcsLocked();
16932        }
16933    }
16934
16935    final void checkExcessivePowerUsageLocked(boolean doKills) {
16936        updateCpuStatsNow();
16937
16938        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16939        boolean doWakeKills = doKills;
16940        boolean doCpuKills = doKills;
16941        if (mLastPowerCheckRealtime == 0) {
16942            doWakeKills = false;
16943        }
16944        if (mLastPowerCheckUptime == 0) {
16945            doCpuKills = false;
16946        }
16947        if (stats.isScreenOn()) {
16948            doWakeKills = false;
16949        }
16950        final long curRealtime = SystemClock.elapsedRealtime();
16951        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16952        final long curUptime = SystemClock.uptimeMillis();
16953        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16954        mLastPowerCheckRealtime = curRealtime;
16955        mLastPowerCheckUptime = curUptime;
16956        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16957            doWakeKills = false;
16958        }
16959        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16960            doCpuKills = false;
16961        }
16962        int i = mLruProcesses.size();
16963        while (i > 0) {
16964            i--;
16965            ProcessRecord app = mLruProcesses.get(i);
16966            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16967                long wtime;
16968                synchronized (stats) {
16969                    wtime = stats.getProcessWakeTime(app.info.uid,
16970                            app.pid, curRealtime);
16971                }
16972                long wtimeUsed = wtime - app.lastWakeTime;
16973                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16974                if (DEBUG_POWER) {
16975                    StringBuilder sb = new StringBuilder(128);
16976                    sb.append("Wake for ");
16977                    app.toShortString(sb);
16978                    sb.append(": over ");
16979                    TimeUtils.formatDuration(realtimeSince, sb);
16980                    sb.append(" used ");
16981                    TimeUtils.formatDuration(wtimeUsed, sb);
16982                    sb.append(" (");
16983                    sb.append((wtimeUsed*100)/realtimeSince);
16984                    sb.append("%)");
16985                    Slog.i(TAG, sb.toString());
16986                    sb.setLength(0);
16987                    sb.append("CPU for ");
16988                    app.toShortString(sb);
16989                    sb.append(": over ");
16990                    TimeUtils.formatDuration(uptimeSince, sb);
16991                    sb.append(" used ");
16992                    TimeUtils.formatDuration(cputimeUsed, sb);
16993                    sb.append(" (");
16994                    sb.append((cputimeUsed*100)/uptimeSince);
16995                    sb.append("%)");
16996                    Slog.i(TAG, sb.toString());
16997                }
16998                // If a process has held a wake lock for more
16999                // than 50% of the time during this period,
17000                // that sounds bad.  Kill!
17001                if (doWakeKills && realtimeSince > 0
17002                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17003                    synchronized (stats) {
17004                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17005                                realtimeSince, wtimeUsed);
17006                    }
17007                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17008                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17009                } else if (doCpuKills && uptimeSince > 0
17010                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17011                    synchronized (stats) {
17012                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17013                                uptimeSince, cputimeUsed);
17014                    }
17015                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17016                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17017                } else {
17018                    app.lastWakeTime = wtime;
17019                    app.lastCpuTime = app.curCpuTime;
17020                }
17021            }
17022        }
17023    }
17024
17025    private final boolean applyOomAdjLocked(ProcessRecord app,
17026            ProcessRecord TOP_APP, boolean doingAll, long now) {
17027        boolean success = true;
17028
17029        if (app.curRawAdj != app.setRawAdj) {
17030            app.setRawAdj = app.curRawAdj;
17031        }
17032
17033        int changes = 0;
17034
17035        if (app.curAdj != app.setAdj) {
17036            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17037            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17038                TAG, "Set " + app.pid + " " + app.processName +
17039                " adj " + app.curAdj + ": " + app.adjType);
17040            app.setAdj = app.curAdj;
17041        }
17042
17043        if (app.setSchedGroup != app.curSchedGroup) {
17044            app.setSchedGroup = app.curSchedGroup;
17045            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17046                    "Setting process group of " + app.processName
17047                    + " to " + app.curSchedGroup);
17048            if (app.waitingToKill != null &&
17049                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17050                app.kill(app.waitingToKill, true);
17051                success = false;
17052            } else {
17053                if (true) {
17054                    long oldId = Binder.clearCallingIdentity();
17055                    try {
17056                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17057                    } catch (Exception e) {
17058                        Slog.w(TAG, "Failed setting process group of " + app.pid
17059                                + " to " + app.curSchedGroup);
17060                        e.printStackTrace();
17061                    } finally {
17062                        Binder.restoreCallingIdentity(oldId);
17063                    }
17064                } else {
17065                    if (app.thread != null) {
17066                        try {
17067                            app.thread.setSchedulingGroup(app.curSchedGroup);
17068                        } catch (RemoteException e) {
17069                        }
17070                    }
17071                }
17072                Process.setSwappiness(app.pid,
17073                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17074            }
17075        }
17076        if (app.repForegroundActivities != app.foregroundActivities) {
17077            app.repForegroundActivities = app.foregroundActivities;
17078            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17079        }
17080        if (app.repProcState != app.curProcState) {
17081            app.repProcState = app.curProcState;
17082            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17083            if (app.thread != null) {
17084                try {
17085                    if (false) {
17086                        //RuntimeException h = new RuntimeException("here");
17087                        Slog.i(TAG, "Sending new process state " + app.repProcState
17088                                + " to " + app /*, h*/);
17089                    }
17090                    app.thread.setProcessState(app.repProcState);
17091                } catch (RemoteException e) {
17092                }
17093            }
17094        }
17095        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17096                app.setProcState)) {
17097            app.lastStateTime = now;
17098            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17099                    isSleeping(), now);
17100            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17101                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17102                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17103                    + (app.nextPssTime-now) + ": " + app);
17104        } else {
17105            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17106                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17107                requestPssLocked(app, app.setProcState);
17108                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17109                        isSleeping(), now);
17110            } else if (false && DEBUG_PSS) {
17111                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17112            }
17113        }
17114        if (app.setProcState != app.curProcState) {
17115            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17116                    "Proc state change of " + app.processName
17117                    + " to " + app.curProcState);
17118            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17119            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17120            if (setImportant && !curImportant) {
17121                // This app is no longer something we consider important enough to allow to
17122                // use arbitrary amounts of battery power.  Note
17123                // its current wake lock time to later know to kill it if
17124                // it is not behaving well.
17125                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17126                synchronized (stats) {
17127                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17128                            app.pid, SystemClock.elapsedRealtime());
17129                }
17130                app.lastCpuTime = app.curCpuTime;
17131
17132            }
17133            app.setProcState = app.curProcState;
17134            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17135                app.notCachedSinceIdle = false;
17136            }
17137            if (!doingAll) {
17138                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17139            } else {
17140                app.procStateChanged = true;
17141            }
17142        }
17143
17144        if (changes != 0) {
17145            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17146            int i = mPendingProcessChanges.size()-1;
17147            ProcessChangeItem item = null;
17148            while (i >= 0) {
17149                item = mPendingProcessChanges.get(i);
17150                if (item.pid == app.pid) {
17151                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17152                    break;
17153                }
17154                i--;
17155            }
17156            if (i < 0) {
17157                // No existing item in pending changes; need a new one.
17158                final int NA = mAvailProcessChanges.size();
17159                if (NA > 0) {
17160                    item = mAvailProcessChanges.remove(NA-1);
17161                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17162                } else {
17163                    item = new ProcessChangeItem();
17164                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17165                }
17166                item.changes = 0;
17167                item.pid = app.pid;
17168                item.uid = app.info.uid;
17169                if (mPendingProcessChanges.size() == 0) {
17170                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17171                            "*** Enqueueing dispatch processes changed!");
17172                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17173                }
17174                mPendingProcessChanges.add(item);
17175            }
17176            item.changes |= changes;
17177            item.processState = app.repProcState;
17178            item.foregroundActivities = app.repForegroundActivities;
17179            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17180                    + Integer.toHexString(System.identityHashCode(item))
17181                    + " " + app.toShortString() + ": changes=" + item.changes
17182                    + " procState=" + item.processState
17183                    + " foreground=" + item.foregroundActivities
17184                    + " type=" + app.adjType + " source=" + app.adjSource
17185                    + " target=" + app.adjTarget);
17186        }
17187
17188        return success;
17189    }
17190
17191    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17192        if (proc.thread != null) {
17193            if (proc.baseProcessTracker != null) {
17194                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17195            }
17196            if (proc.repProcState >= 0) {
17197                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17198                        proc.repProcState);
17199            }
17200        }
17201    }
17202
17203    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17204            ProcessRecord TOP_APP, boolean doingAll, long now) {
17205        if (app.thread == null) {
17206            return false;
17207        }
17208
17209        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17210
17211        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17212    }
17213
17214    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17215            boolean oomAdj) {
17216        if (isForeground != proc.foregroundServices) {
17217            proc.foregroundServices = isForeground;
17218            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17219                    proc.info.uid);
17220            if (isForeground) {
17221                if (curProcs == null) {
17222                    curProcs = new ArrayList<ProcessRecord>();
17223                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17224                }
17225                if (!curProcs.contains(proc)) {
17226                    curProcs.add(proc);
17227                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17228                            proc.info.packageName, proc.info.uid);
17229                }
17230            } else {
17231                if (curProcs != null) {
17232                    if (curProcs.remove(proc)) {
17233                        mBatteryStatsService.noteEvent(
17234                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17235                                proc.info.packageName, proc.info.uid);
17236                        if (curProcs.size() <= 0) {
17237                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17238                        }
17239                    }
17240                }
17241            }
17242            if (oomAdj) {
17243                updateOomAdjLocked();
17244            }
17245        }
17246    }
17247
17248    private final ActivityRecord resumedAppLocked() {
17249        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17250        String pkg;
17251        int uid;
17252        if (act != null) {
17253            pkg = act.packageName;
17254            uid = act.info.applicationInfo.uid;
17255        } else {
17256            pkg = null;
17257            uid = -1;
17258        }
17259        // Has the UID or resumed package name changed?
17260        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17261                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17262            if (mCurResumedPackage != null) {
17263                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17264                        mCurResumedPackage, mCurResumedUid);
17265            }
17266            mCurResumedPackage = pkg;
17267            mCurResumedUid = uid;
17268            if (mCurResumedPackage != null) {
17269                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17270                        mCurResumedPackage, mCurResumedUid);
17271            }
17272        }
17273        return act;
17274    }
17275
17276    final boolean updateOomAdjLocked(ProcessRecord app) {
17277        final ActivityRecord TOP_ACT = resumedAppLocked();
17278        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17279        final boolean wasCached = app.cached;
17280
17281        mAdjSeq++;
17282
17283        // This is the desired cached adjusment we want to tell it to use.
17284        // If our app is currently cached, we know it, and that is it.  Otherwise,
17285        // we don't know it yet, and it needs to now be cached we will then
17286        // need to do a complete oom adj.
17287        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17288                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17289        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17290                SystemClock.uptimeMillis());
17291        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17292            // Changed to/from cached state, so apps after it in the LRU
17293            // list may also be changed.
17294            updateOomAdjLocked();
17295        }
17296        return success;
17297    }
17298
17299    final void updateOomAdjLocked() {
17300        final ActivityRecord TOP_ACT = resumedAppLocked();
17301        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17302        final long now = SystemClock.uptimeMillis();
17303        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17304        final int N = mLruProcesses.size();
17305
17306        if (false) {
17307            RuntimeException e = new RuntimeException();
17308            e.fillInStackTrace();
17309            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17310        }
17311
17312        mAdjSeq++;
17313        mNewNumServiceProcs = 0;
17314        mNewNumAServiceProcs = 0;
17315
17316        final int emptyProcessLimit;
17317        final int cachedProcessLimit;
17318        if (mProcessLimit <= 0) {
17319            emptyProcessLimit = cachedProcessLimit = 0;
17320        } else if (mProcessLimit == 1) {
17321            emptyProcessLimit = 1;
17322            cachedProcessLimit = 0;
17323        } else {
17324            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17325            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17326        }
17327
17328        // Let's determine how many processes we have running vs.
17329        // how many slots we have for background processes; we may want
17330        // to put multiple processes in a slot of there are enough of
17331        // them.
17332        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17333                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17334        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17335        if (numEmptyProcs > cachedProcessLimit) {
17336            // If there are more empty processes than our limit on cached
17337            // processes, then use the cached process limit for the factor.
17338            // This ensures that the really old empty processes get pushed
17339            // down to the bottom, so if we are running low on memory we will
17340            // have a better chance at keeping around more cached processes
17341            // instead of a gazillion empty processes.
17342            numEmptyProcs = cachedProcessLimit;
17343        }
17344        int emptyFactor = numEmptyProcs/numSlots;
17345        if (emptyFactor < 1) emptyFactor = 1;
17346        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17347        if (cachedFactor < 1) cachedFactor = 1;
17348        int stepCached = 0;
17349        int stepEmpty = 0;
17350        int numCached = 0;
17351        int numEmpty = 0;
17352        int numTrimming = 0;
17353
17354        mNumNonCachedProcs = 0;
17355        mNumCachedHiddenProcs = 0;
17356
17357        // First update the OOM adjustment for each of the
17358        // application processes based on their current state.
17359        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17360        int nextCachedAdj = curCachedAdj+1;
17361        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17362        int nextEmptyAdj = curEmptyAdj+2;
17363        for (int i=N-1; i>=0; i--) {
17364            ProcessRecord app = mLruProcesses.get(i);
17365            if (!app.killedByAm && app.thread != null) {
17366                app.procStateChanged = false;
17367                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17368
17369                // If we haven't yet assigned the final cached adj
17370                // to the process, do that now.
17371                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17372                    switch (app.curProcState) {
17373                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17374                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17375                            // This process is a cached process holding activities...
17376                            // assign it the next cached value for that type, and then
17377                            // step that cached level.
17378                            app.curRawAdj = curCachedAdj;
17379                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17380                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17381                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17382                                    + ")");
17383                            if (curCachedAdj != nextCachedAdj) {
17384                                stepCached++;
17385                                if (stepCached >= cachedFactor) {
17386                                    stepCached = 0;
17387                                    curCachedAdj = nextCachedAdj;
17388                                    nextCachedAdj += 2;
17389                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17390                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17391                                    }
17392                                }
17393                            }
17394                            break;
17395                        default:
17396                            // For everything else, assign next empty cached process
17397                            // level and bump that up.  Note that this means that
17398                            // long-running services that have dropped down to the
17399                            // cached level will be treated as empty (since their process
17400                            // state is still as a service), which is what we want.
17401                            app.curRawAdj = curEmptyAdj;
17402                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17403                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17404                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17405                                    + ")");
17406                            if (curEmptyAdj != nextEmptyAdj) {
17407                                stepEmpty++;
17408                                if (stepEmpty >= emptyFactor) {
17409                                    stepEmpty = 0;
17410                                    curEmptyAdj = nextEmptyAdj;
17411                                    nextEmptyAdj += 2;
17412                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17413                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17414                                    }
17415                                }
17416                            }
17417                            break;
17418                    }
17419                }
17420
17421                applyOomAdjLocked(app, TOP_APP, true, now);
17422
17423                // Count the number of process types.
17424                switch (app.curProcState) {
17425                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17426                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17427                        mNumCachedHiddenProcs++;
17428                        numCached++;
17429                        if (numCached > cachedProcessLimit) {
17430                            app.kill("cached #" + numCached, true);
17431                        }
17432                        break;
17433                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17434                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17435                                && app.lastActivityTime < oldTime) {
17436                            app.kill("empty for "
17437                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17438                                    / 1000) + "s", true);
17439                        } else {
17440                            numEmpty++;
17441                            if (numEmpty > emptyProcessLimit) {
17442                                app.kill("empty #" + numEmpty, true);
17443                            }
17444                        }
17445                        break;
17446                    default:
17447                        mNumNonCachedProcs++;
17448                        break;
17449                }
17450
17451                if (app.isolated && app.services.size() <= 0) {
17452                    // If this is an isolated process, and there are no
17453                    // services running in it, then the process is no longer
17454                    // needed.  We agressively kill these because we can by
17455                    // definition not re-use the same process again, and it is
17456                    // good to avoid having whatever code was running in them
17457                    // left sitting around after no longer needed.
17458                    app.kill("isolated not needed", true);
17459                }
17460
17461                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17462                        && !app.killedByAm) {
17463                    numTrimming++;
17464                }
17465            }
17466        }
17467
17468        mNumServiceProcs = mNewNumServiceProcs;
17469
17470        // Now determine the memory trimming level of background processes.
17471        // Unfortunately we need to start at the back of the list to do this
17472        // properly.  We only do this if the number of background apps we
17473        // are managing to keep around is less than half the maximum we desire;
17474        // if we are keeping a good number around, we'll let them use whatever
17475        // memory they want.
17476        final int numCachedAndEmpty = numCached + numEmpty;
17477        int memFactor;
17478        if (numCached <= ProcessList.TRIM_CACHED_APPS
17479                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17480            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17481                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17482            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17483                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17484            } else {
17485                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17486            }
17487        } else {
17488            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17489        }
17490        // We always allow the memory level to go up (better).  We only allow it to go
17491        // down if we are in a state where that is allowed, *and* the total number of processes
17492        // has gone down since last time.
17493        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17494                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17495                + " last=" + mLastNumProcesses);
17496        if (memFactor > mLastMemoryLevel) {
17497            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17498                memFactor = mLastMemoryLevel;
17499                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17500            }
17501        }
17502        mLastMemoryLevel = memFactor;
17503        mLastNumProcesses = mLruProcesses.size();
17504        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17505        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17506        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17507            if (mLowRamStartTime == 0) {
17508                mLowRamStartTime = now;
17509            }
17510            int step = 0;
17511            int fgTrimLevel;
17512            switch (memFactor) {
17513                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17514                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17515                    break;
17516                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17517                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17518                    break;
17519                default:
17520                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17521                    break;
17522            }
17523            int factor = numTrimming/3;
17524            int minFactor = 2;
17525            if (mHomeProcess != null) minFactor++;
17526            if (mPreviousProcess != null) minFactor++;
17527            if (factor < minFactor) factor = minFactor;
17528            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17529            for (int i=N-1; i>=0; i--) {
17530                ProcessRecord app = mLruProcesses.get(i);
17531                if (allChanged || app.procStateChanged) {
17532                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17533                    app.procStateChanged = false;
17534                }
17535                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17536                        && !app.killedByAm) {
17537                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17538                        try {
17539                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17540                                    "Trimming memory of " + app.processName
17541                                    + " to " + curLevel);
17542                            app.thread.scheduleTrimMemory(curLevel);
17543                        } catch (RemoteException e) {
17544                        }
17545                        if (false) {
17546                            // For now we won't do this; our memory trimming seems
17547                            // to be good enough at this point that destroying
17548                            // activities causes more harm than good.
17549                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17550                                    && app != mHomeProcess && app != mPreviousProcess) {
17551                                // Need to do this on its own message because the stack may not
17552                                // be in a consistent state at this point.
17553                                // For these apps we will also finish their activities
17554                                // to help them free memory.
17555                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17556                            }
17557                        }
17558                    }
17559                    app.trimMemoryLevel = curLevel;
17560                    step++;
17561                    if (step >= factor) {
17562                        step = 0;
17563                        switch (curLevel) {
17564                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17565                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17566                                break;
17567                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17568                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17569                                break;
17570                        }
17571                    }
17572                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17573                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17574                            && app.thread != null) {
17575                        try {
17576                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17577                                    "Trimming memory of heavy-weight " + app.processName
17578                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17579                            app.thread.scheduleTrimMemory(
17580                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17581                        } catch (RemoteException e) {
17582                        }
17583                    }
17584                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17585                } else {
17586                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17587                            || app.systemNoUi) && app.pendingUiClean) {
17588                        // If this application is now in the background and it
17589                        // had done UI, then give it the special trim level to
17590                        // have it free UI resources.
17591                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17592                        if (app.trimMemoryLevel < level && app.thread != null) {
17593                            try {
17594                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17595                                        "Trimming memory of bg-ui " + app.processName
17596                                        + " to " + level);
17597                                app.thread.scheduleTrimMemory(level);
17598                            } catch (RemoteException e) {
17599                            }
17600                        }
17601                        app.pendingUiClean = false;
17602                    }
17603                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17604                        try {
17605                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17606                                    "Trimming memory of fg " + app.processName
17607                                    + " to " + fgTrimLevel);
17608                            app.thread.scheduleTrimMemory(fgTrimLevel);
17609                        } catch (RemoteException e) {
17610                        }
17611                    }
17612                    app.trimMemoryLevel = fgTrimLevel;
17613                }
17614            }
17615        } else {
17616            if (mLowRamStartTime != 0) {
17617                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17618                mLowRamStartTime = 0;
17619            }
17620            for (int i=N-1; i>=0; i--) {
17621                ProcessRecord app = mLruProcesses.get(i);
17622                if (allChanged || app.procStateChanged) {
17623                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17624                    app.procStateChanged = false;
17625                }
17626                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17627                        || app.systemNoUi) && app.pendingUiClean) {
17628                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17629                            && app.thread != null) {
17630                        try {
17631                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17632                                    "Trimming memory of ui hidden " + app.processName
17633                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17634                            app.thread.scheduleTrimMemory(
17635                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17636                        } catch (RemoteException e) {
17637                        }
17638                    }
17639                    app.pendingUiClean = false;
17640                }
17641                app.trimMemoryLevel = 0;
17642            }
17643        }
17644
17645        if (mAlwaysFinishActivities) {
17646            // Need to do this on its own message because the stack may not
17647            // be in a consistent state at this point.
17648            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17649        }
17650
17651        if (allChanged) {
17652            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17653        }
17654
17655        if (mProcessStats.shouldWriteNowLocked(now)) {
17656            mHandler.post(new Runnable() {
17657                @Override public void run() {
17658                    synchronized (ActivityManagerService.this) {
17659                        mProcessStats.writeStateAsyncLocked();
17660                    }
17661                }
17662            });
17663        }
17664
17665        if (DEBUG_OOM_ADJ) {
17666            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17667        }
17668    }
17669
17670    final void trimApplications() {
17671        synchronized (this) {
17672            int i;
17673
17674            // First remove any unused application processes whose package
17675            // has been removed.
17676            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
17677                final ProcessRecord app = mRemovedProcesses.get(i);
17678                if (app.activities.size() == 0
17679                        && app.curReceiver == null && app.services.size() == 0) {
17680                    Slog.i(
17681                        TAG, "Exiting empty application process "
17682                        + app.processName + " ("
17683                        + (app.thread != null ? app.thread.asBinder() : null)
17684                        + ")\n");
17685                    if (app.pid > 0 && app.pid != MY_PID) {
17686                        app.kill("empty", false);
17687                    } else {
17688                        try {
17689                            app.thread.scheduleExit();
17690                        } catch (Exception e) {
17691                            // Ignore exceptions.
17692                        }
17693                    }
17694                    cleanUpApplicationRecordLocked(app, false, true, -1);
17695                    mRemovedProcesses.remove(i);
17696
17697                    if (app.persistent) {
17698                        addAppLocked(app.info, false, null /* ABI override */);
17699                    }
17700                }
17701            }
17702
17703            // Now update the oom adj for all processes.
17704            updateOomAdjLocked();
17705        }
17706    }
17707
17708    /** This method sends the specified signal to each of the persistent apps */
17709    public void signalPersistentProcesses(int sig) throws RemoteException {
17710        if (sig != Process.SIGNAL_USR1) {
17711            throw new SecurityException("Only SIGNAL_USR1 is allowed");
17712        }
17713
17714        synchronized (this) {
17715            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
17716                    != PackageManager.PERMISSION_GRANTED) {
17717                throw new SecurityException("Requires permission "
17718                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
17719            }
17720
17721            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17722                ProcessRecord r = mLruProcesses.get(i);
17723                if (r.thread != null && r.persistent) {
17724                    Process.sendSignal(r.pid, sig);
17725                }
17726            }
17727        }
17728    }
17729
17730    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
17731        if (proc == null || proc == mProfileProc) {
17732            proc = mProfileProc;
17733            profileType = mProfileType;
17734            clearProfilerLocked();
17735        }
17736        if (proc == null) {
17737            return;
17738        }
17739        try {
17740            proc.thread.profilerControl(false, null, profileType);
17741        } catch (RemoteException e) {
17742            throw new IllegalStateException("Process disappeared");
17743        }
17744    }
17745
17746    private void clearProfilerLocked() {
17747        if (mProfileFd != null) {
17748            try {
17749                mProfileFd.close();
17750            } catch (IOException e) {
17751            }
17752        }
17753        mProfileApp = null;
17754        mProfileProc = null;
17755        mProfileFile = null;
17756        mProfileType = 0;
17757        mAutoStopProfiler = false;
17758        mSamplingInterval = 0;
17759    }
17760
17761    public boolean profileControl(String process, int userId, boolean start,
17762            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
17763
17764        try {
17765            synchronized (this) {
17766                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17767                // its own permission.
17768                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17769                        != PackageManager.PERMISSION_GRANTED) {
17770                    throw new SecurityException("Requires permission "
17771                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17772                }
17773
17774                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
17775                    throw new IllegalArgumentException("null profile info or fd");
17776                }
17777
17778                ProcessRecord proc = null;
17779                if (process != null) {
17780                    proc = findProcessLocked(process, userId, "profileControl");
17781                }
17782
17783                if (start && (proc == null || proc.thread == null)) {
17784                    throw new IllegalArgumentException("Unknown process: " + process);
17785                }
17786
17787                if (start) {
17788                    stopProfilerLocked(null, 0);
17789                    setProfileApp(proc.info, proc.processName, profilerInfo);
17790                    mProfileProc = proc;
17791                    mProfileType = profileType;
17792                    ParcelFileDescriptor fd = profilerInfo.profileFd;
17793                    try {
17794                        fd = fd.dup();
17795                    } catch (IOException e) {
17796                        fd = null;
17797                    }
17798                    profilerInfo.profileFd = fd;
17799                    proc.thread.profilerControl(start, profilerInfo, profileType);
17800                    fd = null;
17801                    mProfileFd = null;
17802                } else {
17803                    stopProfilerLocked(proc, profileType);
17804                    if (profilerInfo != null && profilerInfo.profileFd != null) {
17805                        try {
17806                            profilerInfo.profileFd.close();
17807                        } catch (IOException e) {
17808                        }
17809                    }
17810                }
17811
17812                return true;
17813            }
17814        } catch (RemoteException e) {
17815            throw new IllegalStateException("Process disappeared");
17816        } finally {
17817            if (profilerInfo != null && profilerInfo.profileFd != null) {
17818                try {
17819                    profilerInfo.profileFd.close();
17820                } catch (IOException e) {
17821                }
17822            }
17823        }
17824    }
17825
17826    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
17827        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17828                userId, true, ALLOW_FULL_ONLY, callName, null);
17829        ProcessRecord proc = null;
17830        try {
17831            int pid = Integer.parseInt(process);
17832            synchronized (mPidsSelfLocked) {
17833                proc = mPidsSelfLocked.get(pid);
17834            }
17835        } catch (NumberFormatException e) {
17836        }
17837
17838        if (proc == null) {
17839            ArrayMap<String, SparseArray<ProcessRecord>> all
17840                    = mProcessNames.getMap();
17841            SparseArray<ProcessRecord> procs = all.get(process);
17842            if (procs != null && procs.size() > 0) {
17843                proc = procs.valueAt(0);
17844                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
17845                    for (int i=1; i<procs.size(); i++) {
17846                        ProcessRecord thisProc = procs.valueAt(i);
17847                        if (thisProc.userId == userId) {
17848                            proc = thisProc;
17849                            break;
17850                        }
17851                    }
17852                }
17853            }
17854        }
17855
17856        return proc;
17857    }
17858
17859    public boolean dumpHeap(String process, int userId, boolean managed,
17860            String path, ParcelFileDescriptor fd) throws RemoteException {
17861
17862        try {
17863            synchronized (this) {
17864                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17865                // its own permission (same as profileControl).
17866                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17867                        != PackageManager.PERMISSION_GRANTED) {
17868                    throw new SecurityException("Requires permission "
17869                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17870                }
17871
17872                if (fd == null) {
17873                    throw new IllegalArgumentException("null fd");
17874                }
17875
17876                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
17877                if (proc == null || proc.thread == null) {
17878                    throw new IllegalArgumentException("Unknown process: " + process);
17879                }
17880
17881                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17882                if (!isDebuggable) {
17883                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
17884                        throw new SecurityException("Process not debuggable: " + proc);
17885                    }
17886                }
17887
17888                proc.thread.dumpHeap(managed, path, fd);
17889                fd = null;
17890                return true;
17891            }
17892        } catch (RemoteException e) {
17893            throw new IllegalStateException("Process disappeared");
17894        } finally {
17895            if (fd != null) {
17896                try {
17897                    fd.close();
17898                } catch (IOException e) {
17899                }
17900            }
17901        }
17902    }
17903
17904    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
17905    public void monitor() {
17906        synchronized (this) { }
17907    }
17908
17909    void onCoreSettingsChange(Bundle settings) {
17910        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17911            ProcessRecord processRecord = mLruProcesses.get(i);
17912            try {
17913                if (processRecord.thread != null) {
17914                    processRecord.thread.setCoreSettings(settings);
17915                }
17916            } catch (RemoteException re) {
17917                /* ignore */
17918            }
17919        }
17920    }
17921
17922    // Multi-user methods
17923
17924    /**
17925     * Start user, if its not already running, but don't bring it to foreground.
17926     */
17927    @Override
17928    public boolean startUserInBackground(final int userId) {
17929        return startUser(userId, /* foreground */ false);
17930    }
17931
17932    /**
17933     * Start user, if its not already running, and bring it to foreground.
17934     */
17935    boolean startUserInForeground(final int userId, Dialog dlg) {
17936        boolean result = startUser(userId, /* foreground */ true);
17937        dlg.dismiss();
17938        return result;
17939    }
17940
17941    /**
17942     * Refreshes the list of users related to the current user when either a
17943     * user switch happens or when a new related user is started in the
17944     * background.
17945     */
17946    private void updateCurrentProfileIdsLocked() {
17947        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17948                mCurrentUserId, false /* enabledOnly */);
17949        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17950        for (int i = 0; i < currentProfileIds.length; i++) {
17951            currentProfileIds[i] = profiles.get(i).id;
17952        }
17953        mCurrentProfileIds = currentProfileIds;
17954
17955        synchronized (mUserProfileGroupIdsSelfLocked) {
17956            mUserProfileGroupIdsSelfLocked.clear();
17957            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17958            for (int i = 0; i < users.size(); i++) {
17959                UserInfo user = users.get(i);
17960                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17961                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17962                }
17963            }
17964        }
17965    }
17966
17967    private Set getProfileIdsLocked(int userId) {
17968        Set userIds = new HashSet<Integer>();
17969        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17970                userId, false /* enabledOnly */);
17971        for (UserInfo user : profiles) {
17972            userIds.add(Integer.valueOf(user.id));
17973        }
17974        return userIds;
17975    }
17976
17977    @Override
17978    public boolean switchUser(final int userId) {
17979        String userName;
17980        synchronized (this) {
17981            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17982            if (userInfo == null) {
17983                Slog.w(TAG, "No user info for user #" + userId);
17984                return false;
17985            }
17986            if (userInfo.isManagedProfile()) {
17987                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
17988                return false;
17989            }
17990            userName = userInfo.name;
17991            mTargetUserId = userId;
17992        }
17993        mHandler.removeMessages(START_USER_SWITCH_MSG);
17994        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
17995        return true;
17996    }
17997
17998    private void showUserSwitchDialog(int userId, String userName) {
17999        // The dialog will show and then initiate the user switch by calling startUserInForeground
18000        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18001                true /* above system */);
18002        d.show();
18003    }
18004
18005    private boolean startUser(final int userId, final boolean foreground) {
18006        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18007                != PackageManager.PERMISSION_GRANTED) {
18008            String msg = "Permission Denial: switchUser() from pid="
18009                    + Binder.getCallingPid()
18010                    + ", uid=" + Binder.getCallingUid()
18011                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18012            Slog.w(TAG, msg);
18013            throw new SecurityException(msg);
18014        }
18015
18016        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18017
18018        final long ident = Binder.clearCallingIdentity();
18019        try {
18020            synchronized (this) {
18021                final int oldUserId = mCurrentUserId;
18022                if (oldUserId == userId) {
18023                    return true;
18024                }
18025
18026                mStackSupervisor.setLockTaskModeLocked(null, false);
18027
18028                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18029                if (userInfo == null) {
18030                    Slog.w(TAG, "No user info for user #" + userId);
18031                    return false;
18032                }
18033                if (foreground && userInfo.isManagedProfile()) {
18034                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18035                    return false;
18036                }
18037
18038                if (foreground) {
18039                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18040                            R.anim.screen_user_enter);
18041                }
18042
18043                boolean needStart = false;
18044
18045                // If the user we are switching to is not currently started, then
18046                // we need to start it now.
18047                if (mStartedUsers.get(userId) == null) {
18048                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18049                    updateStartedUserArrayLocked();
18050                    needStart = true;
18051                }
18052
18053                final Integer userIdInt = Integer.valueOf(userId);
18054                mUserLru.remove(userIdInt);
18055                mUserLru.add(userIdInt);
18056
18057                if (foreground) {
18058                    mCurrentUserId = userId;
18059                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18060                    updateCurrentProfileIdsLocked();
18061                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18062                    // Once the internal notion of the active user has switched, we lock the device
18063                    // with the option to show the user switcher on the keyguard.
18064                    mWindowManager.lockNow(null);
18065                } else {
18066                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18067                    updateCurrentProfileIdsLocked();
18068                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18069                    mUserLru.remove(currentUserIdInt);
18070                    mUserLru.add(currentUserIdInt);
18071                }
18072
18073                final UserStartedState uss = mStartedUsers.get(userId);
18074
18075                // Make sure user is in the started state.  If it is currently
18076                // stopping, we need to knock that off.
18077                if (uss.mState == UserStartedState.STATE_STOPPING) {
18078                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18079                    // so we can just fairly silently bring the user back from
18080                    // the almost-dead.
18081                    uss.mState = UserStartedState.STATE_RUNNING;
18082                    updateStartedUserArrayLocked();
18083                    needStart = true;
18084                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18085                    // This means ACTION_SHUTDOWN has been sent, so we will
18086                    // need to treat this as a new boot of the user.
18087                    uss.mState = UserStartedState.STATE_BOOTING;
18088                    updateStartedUserArrayLocked();
18089                    needStart = true;
18090                }
18091
18092                if (uss.mState == UserStartedState.STATE_BOOTING) {
18093                    // Booting up a new user, need to tell system services about it.
18094                    // Note that this is on the same handler as scheduling of broadcasts,
18095                    // which is important because it needs to go first.
18096                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18097                }
18098
18099                if (foreground) {
18100                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18101                            oldUserId));
18102                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18103                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18104                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18105                            oldUserId, userId, uss));
18106                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18107                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18108                }
18109
18110                if (needStart) {
18111                    // Send USER_STARTED broadcast
18112                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18113                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18114                            | Intent.FLAG_RECEIVER_FOREGROUND);
18115                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18116                    broadcastIntentLocked(null, null, intent,
18117                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18118                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18119                }
18120
18121                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18122                    if (userId != UserHandle.USER_OWNER) {
18123                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18124                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18125                        broadcastIntentLocked(null, null, intent, null,
18126                                new IIntentReceiver.Stub() {
18127                                    public void performReceive(Intent intent, int resultCode,
18128                                            String data, Bundle extras, boolean ordered,
18129                                            boolean sticky, int sendingUser) {
18130                                        onUserInitialized(uss, foreground, oldUserId, userId);
18131                                    }
18132                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18133                                true, false, MY_PID, Process.SYSTEM_UID,
18134                                userId);
18135                        uss.initializing = true;
18136                    } else {
18137                        getUserManagerLocked().makeInitialized(userInfo.id);
18138                    }
18139                }
18140
18141                if (foreground) {
18142                    if (!uss.initializing) {
18143                        moveUserToForeground(uss, oldUserId, userId);
18144                    }
18145                } else {
18146                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18147                }
18148
18149                if (needStart) {
18150                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18151                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18152                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18153                    broadcastIntentLocked(null, null, intent,
18154                            null, new IIntentReceiver.Stub() {
18155                                @Override
18156                                public void performReceive(Intent intent, int resultCode, String data,
18157                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18158                                        throws RemoteException {
18159                                }
18160                            }, 0, null, null,
18161                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18162                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18163                }
18164            }
18165        } finally {
18166            Binder.restoreCallingIdentity(ident);
18167        }
18168
18169        return true;
18170    }
18171
18172    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18173        long ident = Binder.clearCallingIdentity();
18174        try {
18175            Intent intent;
18176            if (oldUserId >= 0) {
18177                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18178                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18179                int count = profiles.size();
18180                for (int i = 0; i < count; i++) {
18181                    int profileUserId = profiles.get(i).id;
18182                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18183                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18184                            | Intent.FLAG_RECEIVER_FOREGROUND);
18185                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18186                    broadcastIntentLocked(null, null, intent,
18187                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18188                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18189                }
18190            }
18191            if (newUserId >= 0) {
18192                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18193                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18194                int count = profiles.size();
18195                for (int i = 0; i < count; i++) {
18196                    int profileUserId = profiles.get(i).id;
18197                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18198                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18199                            | Intent.FLAG_RECEIVER_FOREGROUND);
18200                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18201                    broadcastIntentLocked(null, null, intent,
18202                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18203                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18204                }
18205                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18206                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18207                        | Intent.FLAG_RECEIVER_FOREGROUND);
18208                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18209                broadcastIntentLocked(null, null, intent,
18210                        null, null, 0, null, null,
18211                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18212                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18213            }
18214        } finally {
18215            Binder.restoreCallingIdentity(ident);
18216        }
18217    }
18218
18219    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18220            final int newUserId) {
18221        final int N = mUserSwitchObservers.beginBroadcast();
18222        if (N > 0) {
18223            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18224                int mCount = 0;
18225                @Override
18226                public void sendResult(Bundle data) throws RemoteException {
18227                    synchronized (ActivityManagerService.this) {
18228                        if (mCurUserSwitchCallback == this) {
18229                            mCount++;
18230                            if (mCount == N) {
18231                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18232                            }
18233                        }
18234                    }
18235                }
18236            };
18237            synchronized (this) {
18238                uss.switching = true;
18239                mCurUserSwitchCallback = callback;
18240            }
18241            for (int i=0; i<N; i++) {
18242                try {
18243                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18244                            newUserId, callback);
18245                } catch (RemoteException e) {
18246                }
18247            }
18248        } else {
18249            synchronized (this) {
18250                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18251            }
18252        }
18253        mUserSwitchObservers.finishBroadcast();
18254    }
18255
18256    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18257        synchronized (this) {
18258            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18259            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18260        }
18261    }
18262
18263    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18264        mCurUserSwitchCallback = null;
18265        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18266        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18267                oldUserId, newUserId, uss));
18268    }
18269
18270    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18271        synchronized (this) {
18272            if (foreground) {
18273                moveUserToForeground(uss, oldUserId, newUserId);
18274            }
18275        }
18276
18277        completeSwitchAndInitalize(uss, newUserId, true, false);
18278    }
18279
18280    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18281        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18282        if (homeInFront) {
18283            startHomeActivityLocked(newUserId);
18284        } else {
18285            mStackSupervisor.resumeTopActivitiesLocked();
18286        }
18287        EventLogTags.writeAmSwitchUser(newUserId);
18288        getUserManagerLocked().userForeground(newUserId);
18289        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18290    }
18291
18292    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18293        completeSwitchAndInitalize(uss, newUserId, false, true);
18294    }
18295
18296    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18297            boolean clearInitializing, boolean clearSwitching) {
18298        boolean unfrozen = false;
18299        synchronized (this) {
18300            if (clearInitializing) {
18301                uss.initializing = false;
18302                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18303            }
18304            if (clearSwitching) {
18305                uss.switching = false;
18306            }
18307            if (!uss.switching && !uss.initializing) {
18308                mWindowManager.stopFreezingScreen();
18309                unfrozen = true;
18310            }
18311        }
18312        if (unfrozen) {
18313            final int N = mUserSwitchObservers.beginBroadcast();
18314            for (int i=0; i<N; i++) {
18315                try {
18316                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18317                } catch (RemoteException e) {
18318                }
18319            }
18320            mUserSwitchObservers.finishBroadcast();
18321        }
18322    }
18323
18324    void scheduleStartProfilesLocked() {
18325        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18326            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18327                    DateUtils.SECOND_IN_MILLIS);
18328        }
18329    }
18330
18331    void startProfilesLocked() {
18332        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18333        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18334                mCurrentUserId, false /* enabledOnly */);
18335        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18336        for (UserInfo user : profiles) {
18337            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18338                    && user.id != mCurrentUserId) {
18339                toStart.add(user);
18340            }
18341        }
18342        final int n = toStart.size();
18343        int i = 0;
18344        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18345            startUserInBackground(toStart.get(i).id);
18346        }
18347        if (i < n) {
18348            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18349        }
18350    }
18351
18352    void finishUserBoot(UserStartedState uss) {
18353        synchronized (this) {
18354            if (uss.mState == UserStartedState.STATE_BOOTING
18355                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18356                uss.mState = UserStartedState.STATE_RUNNING;
18357                final int userId = uss.mHandle.getIdentifier();
18358                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18359                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18360                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18361                broadcastIntentLocked(null, null, intent,
18362                        null, null, 0, null, null,
18363                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18364                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18365            }
18366        }
18367    }
18368
18369    void finishUserSwitch(UserStartedState uss) {
18370        synchronized (this) {
18371            finishUserBoot(uss);
18372
18373            startProfilesLocked();
18374
18375            int num = mUserLru.size();
18376            int i = 0;
18377            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18378                Integer oldUserId = mUserLru.get(i);
18379                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18380                if (oldUss == null) {
18381                    // Shouldn't happen, but be sane if it does.
18382                    mUserLru.remove(i);
18383                    num--;
18384                    continue;
18385                }
18386                if (oldUss.mState == UserStartedState.STATE_STOPPING
18387                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18388                    // This user is already stopping, doesn't count.
18389                    num--;
18390                    i++;
18391                    continue;
18392                }
18393                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18394                    // Owner and current can't be stopped, but count as running.
18395                    i++;
18396                    continue;
18397                }
18398                // This is a user to be stopped.
18399                stopUserLocked(oldUserId, null);
18400                num--;
18401                i++;
18402            }
18403        }
18404    }
18405
18406    @Override
18407    public int stopUser(final int userId, final IStopUserCallback callback) {
18408        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18409                != PackageManager.PERMISSION_GRANTED) {
18410            String msg = "Permission Denial: switchUser() from pid="
18411                    + Binder.getCallingPid()
18412                    + ", uid=" + Binder.getCallingUid()
18413                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18414            Slog.w(TAG, msg);
18415            throw new SecurityException(msg);
18416        }
18417        if (userId <= 0) {
18418            throw new IllegalArgumentException("Can't stop primary user " + userId);
18419        }
18420        synchronized (this) {
18421            return stopUserLocked(userId, callback);
18422        }
18423    }
18424
18425    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18426        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18427        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18428            return ActivityManager.USER_OP_IS_CURRENT;
18429        }
18430
18431        final UserStartedState uss = mStartedUsers.get(userId);
18432        if (uss == null) {
18433            // User is not started, nothing to do...  but we do need to
18434            // callback if requested.
18435            if (callback != null) {
18436                mHandler.post(new Runnable() {
18437                    @Override
18438                    public void run() {
18439                        try {
18440                            callback.userStopped(userId);
18441                        } catch (RemoteException e) {
18442                        }
18443                    }
18444                });
18445            }
18446            return ActivityManager.USER_OP_SUCCESS;
18447        }
18448
18449        if (callback != null) {
18450            uss.mStopCallbacks.add(callback);
18451        }
18452
18453        if (uss.mState != UserStartedState.STATE_STOPPING
18454                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18455            uss.mState = UserStartedState.STATE_STOPPING;
18456            updateStartedUserArrayLocked();
18457
18458            long ident = Binder.clearCallingIdentity();
18459            try {
18460                // We are going to broadcast ACTION_USER_STOPPING and then
18461                // once that is done send a final ACTION_SHUTDOWN and then
18462                // stop the user.
18463                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18464                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18465                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18466                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18467                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18468                // This is the result receiver for the final shutdown broadcast.
18469                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18470                    @Override
18471                    public void performReceive(Intent intent, int resultCode, String data,
18472                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18473                        finishUserStop(uss);
18474                    }
18475                };
18476                // This is the result receiver for the initial stopping broadcast.
18477                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18478                    @Override
18479                    public void performReceive(Intent intent, int resultCode, String data,
18480                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18481                        // On to the next.
18482                        synchronized (ActivityManagerService.this) {
18483                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18484                                // Whoops, we are being started back up.  Abort, abort!
18485                                return;
18486                            }
18487                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18488                        }
18489                        mBatteryStatsService.noteEvent(
18490                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18491                                Integer.toString(userId), userId);
18492                        mSystemServiceManager.stopUser(userId);
18493                        broadcastIntentLocked(null, null, shutdownIntent,
18494                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18495                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18496                    }
18497                };
18498                // Kick things off.
18499                broadcastIntentLocked(null, null, stoppingIntent,
18500                        null, stoppingReceiver, 0, null, null,
18501                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18502                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18503            } finally {
18504                Binder.restoreCallingIdentity(ident);
18505            }
18506        }
18507
18508        return ActivityManager.USER_OP_SUCCESS;
18509    }
18510
18511    void finishUserStop(UserStartedState uss) {
18512        final int userId = uss.mHandle.getIdentifier();
18513        boolean stopped;
18514        ArrayList<IStopUserCallback> callbacks;
18515        synchronized (this) {
18516            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18517            if (mStartedUsers.get(userId) != uss) {
18518                stopped = false;
18519            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18520                stopped = false;
18521            } else {
18522                stopped = true;
18523                // User can no longer run.
18524                mStartedUsers.remove(userId);
18525                mUserLru.remove(Integer.valueOf(userId));
18526                updateStartedUserArrayLocked();
18527
18528                // Clean up all state and processes associated with the user.
18529                // Kill all the processes for the user.
18530                forceStopUserLocked(userId, "finish user");
18531            }
18532
18533            // Explicitly remove the old information in mRecentTasks.
18534            removeRecentTasksForUserLocked(userId);
18535        }
18536
18537        for (int i=0; i<callbacks.size(); i++) {
18538            try {
18539                if (stopped) callbacks.get(i).userStopped(userId);
18540                else callbacks.get(i).userStopAborted(userId);
18541            } catch (RemoteException e) {
18542            }
18543        }
18544
18545        if (stopped) {
18546            mSystemServiceManager.cleanupUser(userId);
18547            synchronized (this) {
18548                mStackSupervisor.removeUserLocked(userId);
18549            }
18550        }
18551    }
18552
18553    @Override
18554    public UserInfo getCurrentUser() {
18555        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18556                != PackageManager.PERMISSION_GRANTED) && (
18557                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18558                != PackageManager.PERMISSION_GRANTED)) {
18559            String msg = "Permission Denial: getCurrentUser() from pid="
18560                    + Binder.getCallingPid()
18561                    + ", uid=" + Binder.getCallingUid()
18562                    + " requires " + INTERACT_ACROSS_USERS;
18563            Slog.w(TAG, msg);
18564            throw new SecurityException(msg);
18565        }
18566        synchronized (this) {
18567            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18568            return getUserManagerLocked().getUserInfo(userId);
18569        }
18570    }
18571
18572    int getCurrentUserIdLocked() {
18573        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18574    }
18575
18576    @Override
18577    public boolean isUserRunning(int userId, boolean orStopped) {
18578        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18579                != PackageManager.PERMISSION_GRANTED) {
18580            String msg = "Permission Denial: isUserRunning() from pid="
18581                    + Binder.getCallingPid()
18582                    + ", uid=" + Binder.getCallingUid()
18583                    + " requires " + INTERACT_ACROSS_USERS;
18584            Slog.w(TAG, msg);
18585            throw new SecurityException(msg);
18586        }
18587        synchronized (this) {
18588            return isUserRunningLocked(userId, orStopped);
18589        }
18590    }
18591
18592    boolean isUserRunningLocked(int userId, boolean orStopped) {
18593        UserStartedState state = mStartedUsers.get(userId);
18594        if (state == null) {
18595            return false;
18596        }
18597        if (orStopped) {
18598            return true;
18599        }
18600        return state.mState != UserStartedState.STATE_STOPPING
18601                && state.mState != UserStartedState.STATE_SHUTDOWN;
18602    }
18603
18604    @Override
18605    public int[] getRunningUserIds() {
18606        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18607                != PackageManager.PERMISSION_GRANTED) {
18608            String msg = "Permission Denial: isUserRunning() from pid="
18609                    + Binder.getCallingPid()
18610                    + ", uid=" + Binder.getCallingUid()
18611                    + " requires " + INTERACT_ACROSS_USERS;
18612            Slog.w(TAG, msg);
18613            throw new SecurityException(msg);
18614        }
18615        synchronized (this) {
18616            return mStartedUserArray;
18617        }
18618    }
18619
18620    private void updateStartedUserArrayLocked() {
18621        int num = 0;
18622        for (int i=0; i<mStartedUsers.size();  i++) {
18623            UserStartedState uss = mStartedUsers.valueAt(i);
18624            // This list does not include stopping users.
18625            if (uss.mState != UserStartedState.STATE_STOPPING
18626                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18627                num++;
18628            }
18629        }
18630        mStartedUserArray = new int[num];
18631        num = 0;
18632        for (int i=0; i<mStartedUsers.size();  i++) {
18633            UserStartedState uss = mStartedUsers.valueAt(i);
18634            if (uss.mState != UserStartedState.STATE_STOPPING
18635                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18636                mStartedUserArray[num] = mStartedUsers.keyAt(i);
18637                num++;
18638            }
18639        }
18640    }
18641
18642    @Override
18643    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18644        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18645                != PackageManager.PERMISSION_GRANTED) {
18646            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
18647                    + Binder.getCallingPid()
18648                    + ", uid=" + Binder.getCallingUid()
18649                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18650            Slog.w(TAG, msg);
18651            throw new SecurityException(msg);
18652        }
18653
18654        mUserSwitchObservers.register(observer);
18655    }
18656
18657    @Override
18658    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
18659        mUserSwitchObservers.unregister(observer);
18660    }
18661
18662    private boolean userExists(int userId) {
18663        if (userId == 0) {
18664            return true;
18665        }
18666        UserManagerService ums = getUserManagerLocked();
18667        return ums != null ? (ums.getUserInfo(userId) != null) : false;
18668    }
18669
18670    int[] getUsersLocked() {
18671        UserManagerService ums = getUserManagerLocked();
18672        return ums != null ? ums.getUserIds() : new int[] { 0 };
18673    }
18674
18675    UserManagerService getUserManagerLocked() {
18676        if (mUserManager == null) {
18677            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
18678            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
18679        }
18680        return mUserManager;
18681    }
18682
18683    private int applyUserId(int uid, int userId) {
18684        return UserHandle.getUid(userId, uid);
18685    }
18686
18687    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
18688        if (info == null) return null;
18689        ApplicationInfo newInfo = new ApplicationInfo(info);
18690        newInfo.uid = applyUserId(info.uid, userId);
18691        newInfo.dataDir = USER_DATA_DIR + userId + "/"
18692                + info.packageName;
18693        return newInfo;
18694    }
18695
18696    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
18697        if (aInfo == null
18698                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
18699            return aInfo;
18700        }
18701
18702        ActivityInfo info = new ActivityInfo(aInfo);
18703        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
18704        return info;
18705    }
18706
18707    private final class LocalService extends ActivityManagerInternal {
18708        @Override
18709        public void goingToSleep() {
18710            ActivityManagerService.this.goingToSleep();
18711        }
18712
18713        @Override
18714        public void wakingUp() {
18715            ActivityManagerService.this.wakingUp();
18716        }
18717
18718        @Override
18719        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
18720                String processName, String abiOverride, int uid, Runnable crashHandler) {
18721            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
18722                    processName, abiOverride, uid, crashHandler);
18723        }
18724    }
18725
18726    /**
18727     * An implementation of IAppTask, that allows an app to manage its own tasks via
18728     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
18729     * only the process that calls getAppTasks() can call the AppTask methods.
18730     */
18731    class AppTaskImpl extends IAppTask.Stub {
18732        private int mTaskId;
18733        private int mCallingUid;
18734
18735        public AppTaskImpl(int taskId, int callingUid) {
18736            mTaskId = taskId;
18737            mCallingUid = callingUid;
18738        }
18739
18740        private void checkCaller() {
18741            if (mCallingUid != Binder.getCallingUid()) {
18742                throw new SecurityException("Caller " + mCallingUid
18743                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
18744            }
18745        }
18746
18747        @Override
18748        public void finishAndRemoveTask() {
18749            checkCaller();
18750
18751            synchronized (ActivityManagerService.this) {
18752                long origId = Binder.clearCallingIdentity();
18753                try {
18754                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18755                    if (tr == null) {
18756                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18757                    }
18758                    // Only kill the process if we are not a new document
18759                    int flags = tr.getBaseIntent().getFlags();
18760                    boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
18761                            Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
18762                    removeTaskByIdLocked(mTaskId,
18763                            !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
18764                } finally {
18765                    Binder.restoreCallingIdentity(origId);
18766                }
18767            }
18768        }
18769
18770        @Override
18771        public ActivityManager.RecentTaskInfo getTaskInfo() {
18772            checkCaller();
18773
18774            synchronized (ActivityManagerService.this) {
18775                long origId = Binder.clearCallingIdentity();
18776                try {
18777                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18778                    if (tr == null) {
18779                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18780                    }
18781                    return createRecentTaskInfoFromTaskRecord(tr);
18782                } finally {
18783                    Binder.restoreCallingIdentity(origId);
18784                }
18785            }
18786        }
18787
18788        @Override
18789        public void moveToFront() {
18790            checkCaller();
18791
18792            final TaskRecord tr;
18793            synchronized (ActivityManagerService.this) {
18794                tr = recentTaskForIdLocked(mTaskId);
18795                if (tr == null) {
18796                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18797                }
18798                if (tr.getRootActivity() != null) {
18799                    long origId = Binder.clearCallingIdentity();
18800                    try {
18801                        moveTaskToFrontLocked(tr.taskId, 0, null);
18802                        return;
18803                    } finally {
18804                        Binder.restoreCallingIdentity(origId);
18805                    }
18806                }
18807            }
18808
18809            startActivityFromRecentsInner(tr.taskId, null);
18810        }
18811
18812        @Override
18813        public int startActivity(IBinder whoThread, String callingPackage,
18814                Intent intent, String resolvedType, Bundle options) {
18815            checkCaller();
18816
18817            int callingUser = UserHandle.getCallingUserId();
18818            TaskRecord tr;
18819            IApplicationThread appThread;
18820            synchronized (ActivityManagerService.this) {
18821                tr = recentTaskForIdLocked(mTaskId);
18822                if (tr == null) {
18823                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18824                }
18825                appThread = ApplicationThreadNative.asInterface(whoThread);
18826                if (appThread == null) {
18827                    throw new IllegalArgumentException("Bad app thread " + appThread);
18828                }
18829            }
18830            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
18831                    resolvedType, null, null, null, null, 0, 0, null, null,
18832                    null, options, callingUser, null, tr);
18833        }
18834
18835        @Override
18836        public void setExcludeFromRecents(boolean exclude) {
18837            checkCaller();
18838
18839            synchronized (ActivityManagerService.this) {
18840                long origId = Binder.clearCallingIdentity();
18841                try {
18842                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18843                    if (tr == null) {
18844                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18845                    }
18846                    Intent intent = tr.getBaseIntent();
18847                    if (exclude) {
18848                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18849                    } else {
18850                        intent.setFlags(intent.getFlags()
18851                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18852                    }
18853                } finally {
18854                    Binder.restoreCallingIdentity(origId);
18855                }
18856            }
18857        }
18858    }
18859}
18860